天天看點

Kotlin-27-子協程

目錄

1、子協程

2、父協程

1、子協程

當一個協程在其它協程在中啟動的時候, 它将通過 CoroutineScope.coroutineContext 來承襲上下文,并且這個新協程的 Job 将會成為父協程作業的 子作業。當一個父協程被取消的時候,所有它的子協程也會被遞歸的取消。

然而,當使用 GlobalScope 來啟動一個協程時,則新協程的作業沒有父作業。 是以它與這個啟動的作用域無關且獨立運作。

fun main() = runBlocking<Unit> {
    // 啟動一個協程來處理某種傳入請求(request)
    val request = launch {
        // 孵化了兩個子作業, 其中一個通過 GlobalScope 啟動
        GlobalScope.launch {
            println("job1: 我用GlobalScope啟動,并且獨立執行,不受父協程影響!")
            delay(1000)
            println("job1: 我沒有被取消")
        }
        // 另一個則承襲了父協程的上下文
        launch {
            delay(100)
            println("job2: 我是協程的孩子")
            delay(1000)
            println("job2: 父類被取消後,我也别取消了,是以這裡不會執行。")
        }
    }
    delay(500)
    request.cancel() // 取消請求(request)的執行
    delay(1000) // 延遲一秒鐘來看看發生了什麼
}
//輸出結果
job1: 我用GlobalScope啟動,并且獨立執行,不受父協程影響!
job2: 我是協程的孩子
job1: 我沒有被取消           

2、父協程

一個父協程總是等待所有的子協程執行結束。父協程并不顯式的跟蹤所有子協程的啟動,并且不必使用 Job.join 在最後的時候等待它們完成。
fun main() = runBlocking<Unit> {
    // 啟動一個協程來處理某種傳入請求(request)
    val request = launch {
        repeat(3) { i -> // 啟動少量的子作業
            launch  {
                delay((i + 1) * 200L) // 延遲 200 毫秒、400 毫秒、600 毫秒的時間
                println("協程 $i 執行完成")
            }
        }
        println("request: 父協程執行完成,但是我的子協程仍然活着,直到它們執行完成")
    }
    request.join() // 等待請求的完成,包括其所有子協程
    println("現在所有的協程都執行完成了")
}
//輸出結果
request: 父協程執行完成,但是我的子協程仍然活着,直到它們執行完成
協程 0 執行完成
協程 1 執行完成
協程 2 執行完成
現在所有的協程都執行完成了