协程作用域构建器流程如何工作

Vik*_*rya 4 kotlin kotlin-coroutines

科特林说

  • runBlocking 方法阻塞当前线程等待
  • coroutineScope 只是挂起,释放底层线程以供其他用途。
  • 因此 runBlocking 是一个常规函数,coroutineScope 是一个挂起函数
fun main() = runBlocking { // this: CoroutineScope
    launch { 
        delay(200L)
        println("Task from runBlocking")
    }

    coroutineScope { // Creates a coroutine scope
        launch {
            delay(500L) 
            println("Task from nested launch")
        }

        delay(100L)
        println("Task from coroutine scope") // This line will be printed before the nested launch
    }

    println("Coroutine scope is over") // This line is not printed until the nested launch completes
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中我期望的是:-

  • runBlocking 会阻塞主线程并launch执行它delay(200L)
  • 于是,底层协程被释放并运行,coroutineScope来到delay(500L)&delay(100L)
  • 因此,底层协程再次被释放,并且应该打印println("Coroutine scope is over")

这就是我对runBlocking和的理解coroutineScope。这没有按预期工作。

输出是

Task from coroutine scope
Task from runBlocking
Task from nested launch
Coroutine scope is over
Run Code Online (Sandbox Code Playgroud)

任何人都可以用简单的方式解释一下以理解这一点。

小智 6

launch导致块异步执行,因此调用launch立即返回,协程继续运行,不会等待启动块的执行。

因此,在被调用之后runBlocking,第一个和第二个launch被依次调用,并且紧接着协程被挂起delay(100L)

100ms 后,协程恢复并打印“Task from coroutine scope”,然后嵌套协程作用域块的执行结束。协程作用域总是等待它启动的所有作业执行结束,因此它在这里等待 500 毫秒。

同时,两个启动的块都被执行,因此首先打印“Task from runBlocking”(从开始起200ms后),然后打印“Task fromnested launch”(从开始起500ms后)。

最终,在内部启动的作业完成后,内部协程作用域完成等待,外部协程继续并打印“协程作用域结束”。

这就是故事。我希望它有助于理解代码是如何执行的以及为什么打印顺序是这样的。