fun CoroutineScope.foo(): ReceiveChannel<Response> = produce { send( compute ( "A" )) send( compute ( "B" )) send( compute ( "C" )) } A B C foo() Channel<R> send send send A B C main() fun main() = runBlocking { val channel = foo () for (x in channel) println (x) }
fun CoroutineScope.foo(): ReceiveChannel<Response> = produce { send( compute ( "A" )) send( compute ( "B" )) send( compute ( "C" )) } A B C foo() Channel<R> send send send A B C main() fun main() = runBlocking { val channel = foo () for (x in channel) println (x) }
fun CoroutineScope.foo(): ReceiveChannel<Response> = produce { send( compute ( "A" )) send( compute ( "B" )) send( compute ( "C" )) } A B C foo() Channel<R> send send send A B C main() fun main() = runBlocking { val channel = foo () for (x in channel) println (x) }
fun CoroutineScope.foo(): ReceiveChannel<Response> = produce { send( compute ( "A" )) send( compute ( "B" )) send( compute ( "C" )) } A B C ❌ foo() Channel<R> send send send A B C main() fun main() = runBlocking { val channel = foo () for (x in channel) println (x) }
Channel is hot 🔦
Channel is hot 🔦 fun main() = runBlocking { val channel = foo () for (x in channel) println (x) }
Channel is hot 🔦 fun main() = runBlocking { val channel = foo () // for (x in channel) println (x) }
fun CoroutineScope.foo(): ReceiveChannel<Response> = produce { send( compute ( "A" )) send( compute ( "B" )) send( compute ( "C" )) } foo() Channel main() fun main() = runBlocking { val channel = foo () // for (x in channel) println (x) }
fun CoroutineScope.foo(): ReceiveChannel<Response> = produce { send( compute ( "A" )) send( compute ( "B" )) send( compute ( "C" )) } A foo() 🔦 Channel send main() fun main() = runBlocking { val channel = foo () // for (x in channel) println (x) }
fun CoroutineScope.foo(): ReceiveChannel<Response> 🔦
KOTLIN FLOW Image: Markus Trienke, Sunset over dri6 ice
fun foo(): Flow<Response> = flow { … }
fun foo(): Flow<Response> = flow { … }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } foo() main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } foo() main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } foo() Flow<R> main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } foo() Flow<R> main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } foo() Flow<R> collect main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A foo() Flow<R> collect emit main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A foo() Flow<R> collect emit A main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A foo() Flow<R> collect emit A main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A B foo() Flow<R> collect emit emit A main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A B foo() Flow<R> collect emit emit A B main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A B foo() Flow<R> collect emit emit A B main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A B C foo() Flow<R> collect emit emit emit A B main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A B C foo() Flow<R> collect emit emit emit A B C main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A B C foo() Flow<R> collect emit emit emit A B C main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A B C ❌ foo() Flow<R> collect emit emit emit A B C main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
fun foo(): Flow<Response> = flow { emit( compute ( "A" )) emit( compute ( "B" )) emit( compute ( "C" )) } A B C ❌ foo() Flow<R> collect emit emit emit A B C main() fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
Flow is cold ❄ fun main() = runBlocking { val flow = foo () flow. collect { x -> println (x) } }
Flow is cold ❄ fun main() = runBlocking { val flow = foo () 😄 // flow. collect { x -> println (x) } }
Flow is declara6ve
Flow is declarative fun foo(): Flow<Response> = flow { emit( compute ( "A" )) Declaration emit( compute ( "B" )) emit( compute ( "C" )) }
fun strings(): Flow<String> = flow { emit( "A" ) emit( "B" ) emit( ”C" ) }
fun strings(): Flow<String> = flow { … } fun foo(): Flow<Response> = strings(). map { name -> compute (name) }
fun strings(): Flow<String> = flow { … } fun foo(): Flow<Response> = strings(). map { name -> compute (name) }
fun strings(): Flow<String> = flow { … } fun foo(): Flow<Response> = strings(). map { name -> compute (name) }
fun strings(): Flow<String> = flow { … } fun foo(): Flow<Response> = Operators strings(). map { name -> compute (name) }
fun foo(): Flow<Response> = Operators flowOf ( "A" , "B" , "C" ). map { name -> compute (name) }
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Flow vs List compute (name) } fun foo(): Flow<Response> = flowOf ( "A" , "B" , "C" ). map { name -> compute (name) }
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Runs – Impera:ve Flow vs List compute (name) } fun foo(): Flow<Response> = Defined – Declarative flowOf ( "A" , "B" , "C" ). map { name -> compute (name) } Runs the flow suspend fun <T> Flow<T>.collect(…)
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Runs – Imperative Flow vs List compute (name) } fun foo(): Flow<Response> = Defined – Declara:ve flowOf ( "A" , "B" , "C" ). map { name -> compute (name) } Runs the flow suspend fun <T> Flow<T>.toList(): List<T>
Execu6on order suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Flow vs List compute (name) } fun foo(): Flow<Response> = flowOf ( "A" , "B" , "C" ). map { name -> compute (name) }
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Flow vs List compute (name) A B C } fun foo(): Flow<Response> = flowOf ( "A" , "B" , "C" ). map { name -> compute (name) }
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Flow vs List compute (name) A B C } map fun foo(): Flow<Response> = flowOf ( "A" , "B" , "C" ). map { name -> compute (name) }
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Flow vs List compute (name) A B C } map A’ B’ C’ fun foo(): Flow<Response> = flowOf ( "A" , "B" , "C" ). map { name -> compute (name) }
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Flow vs List compute (name) A B C } map A’ B’ C’ fun foo(): Flow<Response> = flowOf ( "A" , "B" , "C" ). map { name -> compute (name) A } A’
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Flow vs List compute (name) A B C } map A’ B’ C’ fun foo(): Flow<Response> = flowOf ( "A" , "B" , "C" ). map { name -> compute (name) A B } A’ B’
suspend fun foo(): List<Response> = listOf ( "A" , "B" , "C" ). map { name -> Flow vs List compute (name) A B C } map A’ B’ C’ fun foo(): Flow<Response> = flowOf ( "A" , "B" , "C" ). map { name -> compute (name) A B C } React on emi2ed values A’ B’ C’
Flow is reac6ve 🚁 Project RxJava Kotlin Flow Reactor Reactive Streams Specification
Publisher<T> org.reactivestreams Publisher <T>
fun <T : Any> Publisher<T>.asFlow(): Flow<T> org.reactivestreams kotlinx.coroutines.flow Publisher <T> Flow <T>
fun <T : Any> Publisher<T>.asFlow(): Flow<T> org.reactivestreams kotlinx.coroutines.flow Publisher <T> Flow <T> fun <T : Any> Flow<T>.asPublisher(): Publisher<T>
WHY FLOW? What’s the difference?
Flowable<T> Synchronous A fun map(mapper: (T) -> R): Flowable<R> mapper fun flatMapSingle(mapper: (T) -> SingleSource<R>): Flowable<R> A’ Asynchronous
Flowable<T> Synchronous A fun map(mapper: (T) -> R): Flowable<R> mapper fun flatMapSingle(mapper: (T) -> SingleSource<R>): Flowable<R> A’ Asynchronous Synchronous A fun filter(predicate: (T) -> Boolean): Flowable<T> predicate 🤰 A Asynchronous
Recommend
More recommend