👯

Coroutinesを理解したい③

2023/12/02に公開

Overview

前回の続きから
https://zenn.dev/joo_hashi/articles/84096f9dd17a38

https://kotlinlang.org/docs/coroutines-basics.html#scope-builder

さまざまなビルダーによって提供されるコルーチン スコープに加えて、coroutineScope ビルダーを使用して独自のスコープを宣言することができます。 コルーチン スコープを作成しますが、起動されたすべての子が完了するまで完了しません。

runBlocking ビルダーと coroutineScope ビルダーは、両方とも本体とそのすべての子の完了を待機するため、似ているように見えます。 主な違いは、runBlocking メソッドは現在のスレッドを待機のためにブロックするのに対し、coroutineScope は単に一時停止し、基礎となるスレッドを他の用途のために解放することです。 その違いにより、runBlocking は通常の関数であり、coroutineScope は一時停止関数です。

summary

任意の中断関数から coroutineScope を使用できます。 たとえば、Hello と World の同時出力を一時停止 fun doWorld() 関数に移動できます。

任意の中断関数から coroutineScope を使用できます。 たとえば、Hello と World の同時出力を一時停止 fun doWorld() 関数に移動できます。

import kotlinx.coroutines.*

fun main() = runBlocking {
    doWorld()
}

suspend fun doWorld() = coroutineScope {  // this: CoroutineScope
    launch {
        delay(1000L)
        println("World!")
    }
    println("Hello")
}

前回のコードはこちら。よく見ると、coroutineScopeがないですね!!!

import kotlinx.coroutines.*

fun main() = runBlocking { // これは、コルーチンスコープです
    launch { doWorld() }// 新しいコルーチンをバックグラウンドで開始し、続行
    println("Hello")
}

// これはあなたのはじめてのsuspend関数です
suspend fun doWorld() {
    delay(1000L)
    println("World!")
}

thoughts

coroutineScope ビルダーを使用すると、独自のスコープを自分で宣言することができることが理解できた。これいるのだろうかといまだに疑問ですが...

for文で、仮のAPIのデータということにしてるListのデータを1秒ごとにループするコードを書いてみました。

import kotlinx.coroutines.*

fun main() = runBlocking {
    doWorld()
}

suspend fun doWorld() = c {  // this: CoroutineScope
    launch {
        // 仮のAPIのデータを再現した変数
        val apiData = listOf("晴れ", "雨","曇り","雪","霧")
        // 1秒づつfor文で出力
        for (i in apiData) {
            println(i)
            delay(1000L)
        }
    }
    println("call api")
}

もし、CoroutineScopeがない状態でRunするとエラーが出ます!

結論。非同居処理がスコープの中で発生しているようで、CoroutineScopeがないとクラッシュしてしまうようです。

Discussion