在挂起函数上调用await()不能正常工作

时间:2019-04-09 07:18:39

标签: android kotlin coroutine

private val coroutineSupervisor = SupervisorJob()
protected val dispatcherProvider = CoroutineDispatcherProvider()
protected val viewModelScope = CoroutineScope(dispatcherProvider.main + coroutineSupervisor)

class CoroutineDispatcherProvider {

    val main: CoroutineDispatcher
        get() = Dispatchers.Main

    val background: CoroutineDispatcher
        get() = Dispatchers.IO
}

viewModelScope.launch {
    ...
    runBlocking {
        async { firstNumber() }.await()
        async { secondNumber() }.await()
        async { test() }.await()
        async { thirdNumber() }.await()
    }
}

suspend fun firstNumber(): Int {
    delay(3_000) // 3 seconds delay
    return 5
}
suspend fun secondNumber(): Int {
    delay(5_000) // 5 seconds delay
    return 8
}
suspend fun thirdNumber(): Int {
    delay(7_000) // 7 seconds delay
    return 10
}

suspend fun test() {
    withContext(dispatcherProvider.background) {
        ...
    }
}

几天前开始学习协程,我发现有些奇怪。 firstNumber,secondNumber和thirdNumber函数按应有的方式运行-延迟完成,然后下一个函数按正确的顺序执行,但test()却没有。稍后它会返回值,并且在发生这种情况时runBlocking已经完成。我想确保得到结果,然后以某种方式在其他请求中使用它。是因为我在那里使用了某种错误的调度程序还是什么?

1 个答案:

答案 0 :(得分:1)

这是东西。通过异步并等待调用test()方法时,您期望的是等待它完成。

但是,由于您在测试方法中有一个回调流(apiclient调用),因此它将在从服务器获得响应之前立即返回并退出测试方法。响应就绪后,将调用稍后的回调lambda。到此时,运行阻塞已经完成。

所以您应该做的是将您的回调转换为Coroutine。 Codelabs-example

您可以在api调用之外创建一系列Deferred对象,然后等待每个对象。