×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
Coroutines Flow 入門 Kenji Abe
Slide 2
Slide 2 text
Coroutines Flow とは •雑に言うと、RxJavaみたいなやつ •Cold Stream ‣ 受信しはじめてから動き始める ‣ Hot Stream は Channel
Slide 3
Slide 3 text
Coroutines Flow とは • ↓ の資料が分かりやすいので、そっちを見て ‣ https://speakerdeck.com/sys1yagi/5fen- tewakarukotlin-coroutines-flow •この資料では色々な使い方を紹介します
Slide 4
Slide 4 text
基本的なやつ fun main() = runBlocking { val flow = flow { repeat(3) { emit(it) } } flow.collect { println(it) } }
Slide 5
Slide 5 text
基本的なやつ fun main() = runBlocking { val flow = flow { repeat(3) { emit(it) } } flow.collect { println(it) } } Flow builder
Slide 6
Slide 6 text
基本的なやつ fun main() = runBlocking { val flow = flow { repeat(3) { emit(it) } } flow.collect { println(it) } } 値を送出
Slide 7
Slide 7 text
基本的なやつ fun main() = runBlocking { val flow = flow { repeat(3) { emit(it) } } flow.collect { println(it) } } 値を受信
Slide 8
Slide 8 text
Flow builders •Flow { } •flowOf(...) ‣ flowOf(1, 2, 3) •(() -> T).asFlow() ‣ ({ 1 }).asFlow()
Slide 9
Slide 9 text
Intermediate operators •map •filter •take •zip
Slide 10
Slide 10 text
Flow operators fun main() = runBlocking { val flow = flowOf(1, 2, 3, 4, 5) flow.map { it * 2 }.collect { println(it) } } 値を2倍
Slide 11
Slide 11 text
Flow operators fun main() = runBlocking { val flow = flowOf(1, 2, 3, 4, 5) flow.filter { it % 2 == 0 }.collect { println(it) } } 偶数のみ
Slide 12
Slide 12 text
Terminal operators •collect •single •reduce •toList
Slide 13
Slide 13 text
Terminal operators fun main() = runBlocking { val flow = flowOf(1, 2, 3, 4, 5) val value = flow .filter { it == 5 } .single() println(value) // 5 } 複数の値の場合は例外になる
Slide 14
Slide 14 text
Terminal operators fun main() = runBlocking { val flow = flowOf(1, 2, 3, 4, 5) val value = flow .reduce { accumulator, value -> accumulator + value } // 1 + 2 + 3 + 4 + 5 println(value) // 15 }
Slide 15
Slide 15 text
Terminal operators fun main() = runBlocking { val flow = flowOf(1, 2, 3, 4, 5) val value = flow .toList() println(value) // [1, 2, 3, 4, 5] }
Slide 16
Slide 16 text
Change context •flowOn ‣ 上流のContextを変更する ‣ Flowにおいて唯一Contextを切り替える方法 •emitするときにContextが異なると例外
Slide 17
Slide 17 text
Change context fun main() = runBlocking { val flow = flowOf(1, 2, 3, 4, 5) flow .map { println("map: ${Thread.currentThread().name}") it + 1 } .flowOn(Dispatchers.IO) .collect { println("collect: ${Thread.currentThread().name}") } } worker main
Slide 18
Slide 18 text
Change context fun main() = runBlocking { val flow = flowOf(1, 2, 3, 4, 5) flow .map { } .flowOn(Dispatchers.IO) .filter { } .flowOn(Dispatchers.Default) .map { } .flowOn(Dispatchers.IO) .collect { } }
Slide 19
Slide 19 text
Change context fun main() = runBlocking { val flow = flowOf(1, 2, 3, 4, 5) flow .map { } .flowOn(Dispatchers.IO) .flowOn(Dispatchers.Default) .collect { } } 最初のやつが優先
Slide 20
Slide 20 text
Change context fun main() = runBlocking { val flow = flow { emit(1) launch { emit(2) } } flow.collect { } } emit時にContextが違うので 例外になる
Slide 21
Slide 21 text
Exception •catchを使って捕捉できる •上流のストリームの例外のみ捕捉 •onCompletionでfinallyみたいなこともできる
Slide 22
Slide 22 text
Exception fun main() = runBlocking { flow { } .map { } .catch { } .map { } .catch { } .collect { } } ① ② ③ ③の例外はここで捕捉 ①と②の例外はここで捕捉 それ以降は実行されない
Slide 23
Slide 23 text
Exception fun main() = runBlocking { flow { emit(1) }.catch { emit(-1) }.collect { println(it) } } 例外発生時に別の値を送出
Slide 24
Slide 24 text
Exception fun main() = runBlocking { flow { } .map { } .onCompletion { } .map { } .onCompletion { } .collect { } } finallyみたいなやつ
Slide 25
Slide 25 text
おわり