Использование 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)
}