Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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
おわり