定位JavaScript时在Kotlin协程中使用runBlocking?

时间:2018-09-18 19:16:51

标签: kotlin kotlin-coroutines kotlin-js

是否可以在下面编写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进行编译时运行良好。 由于不存在函数runBlocking

,在定位JavaScript时会发出编译错误

1 个答案:

答案 0 :(得分:2)

您的主要问题是您没有要求真正需要的东西。您编写的代码将启动协程,将其挂起,然后阻塞直到完成。这完全等同于根本没有协程,而只是发出阻塞的网络请求,这是您不可能期望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)
}