LoginSignup
1
0

More than 3 years have passed since last update.

Kotlin 1.3のCoroutineのサスペンド関数の合成①(シーケンシャル処理がデフォルト)

Posted at

検証環境

この記事の内容は、以下の環境で検証しました。

  • Intellij IDEA ULTIMATE 2018.2
  • Kotlin 1.3.0
  • Gradle Projectで作成
  • GradleファイルはKotlinで記述(KotlinでDSL)

準備

詳細は下記の準備を参照してください。
https://qiita.com/naoi/items/8abf2cddfc2cb3802daa

Sequential by default

前回に引き続き、公式サイトを読み解いていきます。

タイトルが意味不明です。
読み進めたほうがいい気がします。

Assume that we have two suspending functions defined elsewhere that do something useful like some kind of remote service call or computation. We just pretend they are useful, but actually each one just delays for a second for the purpose of this example:

訳すと

例えば、リモート処理や計算処理に便利なサスペンド関数が2つ定義されていたとします。
今回は、サンプルコードなので10秒間遅延させています。

まずは、前提の関数を確認するということですね。サンプルコードを確認してみます。

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

説明にあったとおりのサスペンド関数が定義されています。

続けて読み進めます。

What do we do if need to invoke them sequentially – first doSomethingUsefulOne and then doSomethingUsefulTwo and compute the sum of their results? In practice we do this if we use the results of the first function to make a decision on whether we need to invoke the second one or to decide on how to invoke it.

We use a normal sequential invocation, because the code in the coroutine, just like in the regular code, is sequential by default. The following example demonstrates it by measuring the total time it takes to execute both suspending functions:

訳すと

はじめにdoSomethingUsefulOne関数を呼び出しその後に、doSomethingUsefulTwo関数を呼び出すとしたら、私達はどうするでしょうか。
はじめに呼び出した関数の結果を以て、その次の関数を呼び出すかどうかを判断します。

コルーチン内のコードは通常のmain関数などと同じ様にシーケンシャルに処理が実行されます。
サンプルコードではコルーチンが完了する時間を計測しています。

ここにきて、はじめて「そうだったのか」と考えてしまいますね。
確かにコルーチン内で更に非同期などはしていませんでした。
サンプルコードはそれぞれの関数で1秒遅延しているので2秒位かかるはずです。
サンプルコードと実行結果を確認してみます。

import kotlinx.coroutines.*
import kotlin.system.*

fun main() = runBlocking<Unit> {
    val time = measureTimeMillis {
        val one = doSomethingUsefulOne()
        val two = doSomethingUsefulTwo()
        println("The answer is ${one + two}")
    }
    println("Completed in $time ms")
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

実行結果
text
The answer is 42
Completed in 2012 ms

確かに2秒位かかってます。
measureTimeMillis関数については下記を参照してください。
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.system/measure-time-millis.html

まとめ

このブロックで理解できたことは以下のことだと思います。

  • コルーチン内はシーケンシャルに処理が進む
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0