嵌套的 Kotlin 协程作用域如何工作?

问题描述 投票:0回答:1

我正在学习 Kotlin 协程,我试图了解协程作用域。根据 Kotlin 指南中的结构化并发

在其所有子协程完成之前,外部作用域无法完成。

我创建了一个示例,如下所示:

fun exampleCoroutine() {
        println("Corutine started")
        runBlocking {
            launch {
                delay(2000)
                launch { //child launch
                    println("nested child")
                }
                println("parent")
            }
            launch {
                delay(1000)
                println("in the second coroutine")
            }
            println("Hello")
        }
    }

我得到以下输出

Corutine started
Hello
in the second coroutine
parent 
nested child 

根据我对协程作用域如何工作的理解,我假设“嵌套子”将在“父”之前打印。由于情况显然并非如此,我想知道为什么“嵌套子级”在“父级”之后打印。

如果我的理解有误,欢迎指正。

kotlin concurrency kotlin-coroutines
1个回答
0
投票

来自

launch
的文档:

启动一个新的协程而不阻塞当前线程,并返回对协程的引用作为

Job

换句话说,它启动一个协程并立即返回。启动的协程“异步”执行。另请注意,launch

不是
suspend 函数。
查看以下代码段:

launch { // parent launch delay(2000) launch { //child launch println("nested child") } println("parent") }

这句话是说“父”
launch

创建的协程无法

完成
,直到“子”launch
完成
创建的子协程。块中的最后一个打印语句不是协程完成时的。当块返回时,协程完成,并且如引用中所述,所有子协程也已完成。 如果您利用

invokeOnCompletion

返回的 Job

 对象中的 
launch
,您可以更好地看到这一点。例如以下内容:
import kotlinx.coroutines.*

fun main(): Unit = runBlocking {
    launch {
        delay(1000)
        launch {
            delay(1000)
            println("Child-1 end")
        }.invokeOnCompletion { println("Child-1 complete") }
        println("Parent-1 end")
    }.invokeOnCompletion { println("Parent-1 complete") }

    launch {
        delay(2000)
        println("Parent-2 end")
    }.invokeOnCompletion { println("Parent-2 complete") }
}

Kotlin 游乐场:

https://pl.kotl.in/Oar099RZs 输出:

Parent-1 end Parent-2 end Parent-2 complete Child-1 end Child-1 complete Parent-1 complete

请注意,虽然“Parent-1”的
最后一条语句

是在“Child-1”完成之前执行的,但“Parent-1”直到“Child-1”完成之后才完成

© www.soinside.com 2019 - 2024. All rights reserved.