AsyncRestTemplate + сопрограммы - PullRequest
0 голосов
/ 07 апреля 2020

Я знаю, что AsyncRestTemplate устарела, но все равно. Правильно ли я пишу такой код, чтобы жениться на AsyncRestTemplate с сопрограммами?

   suspend fun dodo(url: URL): String {
      val result = AsyncRestTemplate().getForEntity(url, String::class.java)
      return result.awaitBody()
   }

   suspend fun <T> ListenableFuture<ResponseEntity<T>>.awaitBody(): T {
      while (this.isDone.not)
         yield()
      return this.get().body!!
   }

1 Ответ

1 голос
/ 07 апреля 2020

Ваш код верен, но неэффективен, так как это фактически ожидание занятости l oop повторный вызов ListenableFuture.isDone до его завершения.

Вы должны использовать API обратного вызова, предоставляемый всякий раз, когда вам нужно выполнить преобразование между асинхронным c API и функциями приостановки:

suspend fun <T> ListenableFuture<T>.await(): T = suspendCancellableCoroutine { cont ->
    // Special handling for Future<*> objects
    cont.cancelFutureOnCancellation(this)

    addCallback(object : ListenableFutureCallback<T> {
        override fun onFailure(ex: Throwable) {
            cont.resumeWithException(ex)
        }

        override fun onSuccess(result: T) {
            cont.resume(result)
        }
    })
}

Это не приведет к потере времени на проверку, завершится ли будущее, а просто скажет будущему возобновить приостановленную функцию, когда результат будет фактически доступен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...