kotlin coroutine async CoroutineStart.LAZY の使い方メモ

例えば async を使った次のコードがあるとします。

class ComposingSuspendingFunctions {

    private suspend fun doSomethingUsefulOne(): Int {
        delay(100L)
        return 13
    }

    private suspend fun doSomethingUsefulTwo(): Int {
        delay(1000L)
        return 29
    }

    @OptIn(ExperimentalCoroutinesApi::class, ExperimentalTime::class)
    @Test
    fun concurrentUsingAsync() = runTest {
        val time = testTimeSource.measureTime {
            val one = async { doSomethingUsefulOne() }
            val two = async { doSomethingUsefulTwo() }
            println("${one.await() + two.await()}")
        }
        assertEquals(Duration.parse("1s"), time)
    }
}

doSomethingUsefulOnedoSomethingUsefulTwo をそれぞれ非同期的に呼び出しているので1秒で処理が完了していますね。

asyncは(もしかするとJobも?)必要になったタイミングでコルーチンを実行することもできるようです。

    @OptIn(ExperimentalCoroutinesApi::class, ExperimentalTime::class)
    @Test
    fun lazilyStartedAsync() = runTest {
        val time = testTimeSource.measureTime {
            val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
            val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
            println("${one.await() + two.await()}")
        }
        assertEquals(Duration.parse("1.1s"), time)
    }

これは、 one.await() のタイミングで実際に計算が走ります。次に two.await() でも計算が走ります。任意のタイミングで、コルーチンを実行できるということです。

これを使えば不要なコルーチンを実行せずにすむため、リソースの節約になりそうです。