协程await()函数不会等到完成工作

时间:2020-11-12 02:26:48

标签: android kotlin-coroutines

我有一个类似下面的代码

fun main() {
    viewModelScope.launch {
        doA()
        //call api with Flow as the return type
    }
}
suspend fun doA() {
    viewModelScope.async { doB() }.await()
}
suspend fun doB() {
    //Do logic here, eventually will call line below
    viewModelScope.launch { doC() }
}
suspend fun doC() {
    //call api with Flow as the return type
}

我在这里想要实现的是使doA()等待完成,然后继续执行其下面的函数,即调用API函数。但是当我尝试运行时,doA()不要等到一切都完成了。调试对我很有帮助,我发现当运行doB()并到达doC()(在新范围内)时,程序将继续执行{{1}中doA()之后的下一行。 }}。

有什么我想念的吗?为什么代码不能像我想要的那样工作?我对协程说了一种新的话。是的,我在Android环境中运行代码。感谢您的帮助

2 个答案:

答案 0 :(得分:1)

我也是初学者。根据我的有限理解,应该使用“异步”来运行“并行”作业并等待“未来结果”

为使作业“顺序”完成,应使用“启动”和“加入”。请检查Waiting for a job

关于doB()运行时doA()的完成,这是因为在doB()中启动了一个新的协程,并立即返回,因此执行将继续执行doA()中的下一行。要使doA()等待,请在启动协同程序时在doB()中添加“ join”

fun main() {
    viewModelScope.launch {
        doA()
        //call api with Flow as the return type
    }
}
suspend fun doA() {
    //viewModelScope.async { doB() }.await()

    // Replace with "launch" and "join"
    viewModelScope.launch{ doB() }.join()
}
suspend fun doB() {
    //Do logic here, eventually will call line below
    //viewModelScope.launch { doC() }

    // Add join() to make it wait 
    viewModelScope.launch { doC() }.join()
}
suspend fun doC() {
    //call api with Flow as the return type
}

但是如果您希望继续使用“异步”,则只需在doB()中添加“ join”

suspend fun doB() {
    //Do logic here, eventually will call line below
    //viewModelScope.launch { doC() }

    // Add join() to make it wait
    viewModelScope.launch { doC() }.join()
}

答案 1 :(得分:0)

对于doB()doC(),您要创建要运行的新协程,因此它不能与doA()在相同的协程中运行。因此,从技术上讲doA()已完成其执行。要让doA()等待,您必须在同一协程中运行doB()和doC()。

suspend fun doA() {
    doB()
}
suspend fun doB() {
    //Do logic here, eventually will call line below
   doC()
}
suspend fun doC() {
    //call api with Flow as the return type
}

另外,如果您像async-await那样在await之后立即使用async,因为它与viewModelScope.async { doB() }.await()相同。