Использование runBlocking в Kotlin Coroutines при ориентации на JavaScript?

Есть ли способ написать код Kotlin ниже, чтобы он компилировался и работал одинаково на JVM и в JavaScript?

fun <A: Any> request(request: Any): A  = runBlocking {
    suspendCoroutine<A> { cont ->
        val subscriber = { response: A ->
                cont.resume(response)
        }
        sendAsync(request, subscriber)
    }
}


fun <Q : Any, A : Any> sendAsync(request: Q, handler: (A) -> Unit) {

    // request is sent to a remote service,
    // when the result is available it is passed to handler(... /* result */)

}

Код компилируется и отлично работает при компиляции для целевой JVM. При компоновке JavaScript выдается ошибка компиляции из-за несуществующей функции runBlocking

1 ответ

Решение

Ваша главная проблема в том, что вы не просите то, что вам действительно нужно. Код, который вы написали, запускает сопрограмму, приостанавливает ее, а затем блокирует до тех пор, пока это не будет сделано. Это в точности равносильно отсутствию сопрограмм и простому блокированию сетевого запроса, чего нельзя ожидать от JavaScript.

Что вам на самом деле нужно сделать, это вернуться на сайт вызова request() и завернуть его в launch:

GlobalScope.launch(Dispatchers.Default) {
    val result: A = request(...)
    // work with the result
}

Имея это в виду, вы можете переписать вашу функцию запроса в

suspend fun <A: Any> request(request: Any): A = suspendCancellableCoroutine {
    sendAsync(request, it::resume)
}
Другие вопросы по тегам