コルーチンのFlowは非同期データストリーム
非同期とは?
-> 二つの関数が一つ実行後終了し、次の関数を実行するのではなく、二つを同時に実行可能なことを非同期といいます。そして、仕事を終えて返すことが コールバック
データストリームとは?
データを消費する消費者とデータを発行する発行者がおり、発行者は消費者に対して継続的にデータを発行することです。
コルーチンでデータストリームを使うためにFlowを使用します。
Flowのデータの核心は次の3つで構成されます。
- 生産者 (Producer)
- 中間演算子 (Intermediary)
- 消費者 (Consumer)
1. 生産者 (Producer)
生産者はデータを発行する役割を持ちます。
fun flowSomething(): Flow<Int> = flow { // flowブロック宣言
repeat(10) { // 数字の繰り返し
emit(Random.nextInt(0, 500)) // ランダム数字の発行
delay(100L)
}
}
2. 中間演算子 (Intermediary)
生産者がデータを生成したら、中間演算子はデータの修正を行います。
aというオブジェクトを発行した後、bというオブジェクトと交換できます。
中間演算子は生産者、消費者のような必須要素ではありません。
Flowがサポートする代表的な中間演算子
- map (データ変形)
- filter (データフィルタリング)
- onEach (データ演算実行)
fun main1() = runBlocking {
flowSomething().map {
"$it $it"
}.collect { value ->
println(value)
}
}
fun main2() = runBlocking {
(1..20).asFlow().filter {
(it % 2) == 0
}.collect {
println(it)
}
}
3. 消費者 (Consumer)
中間演算子が生産者が生成したデータを変換した後、消費者にデータを伝達します。
Flowではcollectを使用してデータを伝達し、消費します。
しかし、collectは複数のイベントで使用できません。複数のイベントを使用することができる launchInが好まれます
消費者はUIを表し、ViewModelで必要な処理をviewで表示するものです。
fun events(): Flow<Int> = (1..3).asFlow().onEach { delay(100) }
fun main() = runBlocking {
events()
.onEach { events -> println("Event: $events") }
.collect() // 複数のイベントに使用できない UI、ネットワーク呼び出し等
println("Done")
}
fun readDateDatas(date: String) {
viewModelScope.launch {
repository.readDateData(date).collect {
readDateData ->
}
}
}