flowOn en buffer: context en backpressure
Wijzig de emissiecontext met flowOn en buffer emissies voor backpressure.
flowOn en buffer: context en backpressure is een gratis Kotlin Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Kotlin Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Kotlin Academy bevat in totaal 4 lessen.
Flow-context
Standaard wordt een flow uitgevoerd in de context van de coroutine die collect aanroept. De dispatcher van de producent en de consument is hetzelfde, tenzij je dit verandert.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
flow {
println("emit on: ${Thread.currentThread().name}")
emit(1)
}.collect {
println("collect on: ${Thread.currentThread().name}")
}
}flowOn wijzigt de context stroomopwaarts
flowOn(dispatcher) voert de flow stroomopwaarts (alles erboven in de keten) uit op de opgegeven dispatcher, terwijl het verzamelen doorgaat op de dispatcher van de aanroeper.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
flow {
println("emit: ${Thread.currentThread().name}")
emit(1)
}.map {
println("map: ${Thread.currentThread().name}")
it * 2
}.flowOn(Dispatchers.Default) // above runs on Default
.collect {
println("collect: ${Thread.currentThread().name}")
}
}Meerdere flowOn-operators in een keten
Je kunt flowOn meerdere keren gebruiken. Elke instantie beïnvloedt de operators er direct boven, tot aan de vorige flowOn.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
flow { emit(1) }
.map { it + 1 }.flowOn(Dispatchers.IO) // map runs on IO
.map { it * 2 }.flowOn(Dispatchers.Default) // this map runs on Default
.collect { println("Result: $it") } // collect on Main (runBlocking)
}Het probleem van terugdruk
Wanneer de producent sneller waarden uitzendt dan de verzamelaar ze kan verwerken, stapelen de waarden zich op. Zonder buffering moet de producent daardoor wachten.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val time = System.currentTimeMillis()
flow {
repeat(3) { i ->
delay(100) // fast producer
emit(i)
}
}.collect {
delay(300) // slow consumer
println("Got $it in ${System.currentTimeMillis() - time}ms")
}
}De operator buffer()
buffer() voert de producent en consument gelijktijdig uit in afzonderlijke coroutines en buffert uitgezonden waarden in een kanaal. De producent hoeft niet op de consument te wachten.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val time = System.currentTimeMillis()
flow {
repeat(3) { i -> delay(100); emit(i) }
}.buffer() // producer and consumer run concurrently
.collect {
delay(300)
println("Got $it in ${System.currentTimeMillis() - time}ms")
}
}Buffercapaciteit
buffer(capacity) stelt de buffergrootte van het kanaal in. Wanneer de buffer vol is, wordt de producent onderbroken (terugdruk). De standaardcapaciteit is 64.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.channels.Channel
fun main() = runBlocking {
flow { repeat(5) { emit(it) } }
.buffer(Channel.RENDEZVOUS) // 0: producer waits
// .buffer(Channel.BUFFERED) // default: 64
// .buffer(Channel.UNLIMITED) // unbounded
.collect { delay(50); println(it) }
}conflate() voor alleen de nieuwste waarde
conflate() verwijdert tussenliggende waarden wanneer de verzamelaar traag is, zodat alleen de meest recente waarde overblijft. Dit is nuttig voor de status van een gebruikersinterface.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
flow {
repeat(5) { i -> emit(i); delay(50) }
}.conflate()
.collect { i ->
delay(150)
println("Collected: $i") // skips some values
}
}collectLatest voor trage verzamelaars
collectLatest annuleert het huidige verzamelblok wanneer een nieuwe waarde binnenkomt en start het opnieuw met de nieuwste waarde.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
flow {
emit(1); delay(50)
emit(2); delay(50)
emit(3)
}.collectLatest { value ->
println("Processing $value")
delay(100) // gets cancelled if new value arrives
println("Done $value") // only prints for last value
}
}Patroon flowOn + buffer
Combineer flowOn en buffer: voer de producent uit op IO (netwerk/schijf), buffer de resultaten en verzamel ze op Main.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun fetchItems(): Flow<String> = flow {
repeat(3) { i ->
delay(100) // simulate IO
emit("item-$i")
}
}.flowOn(Dispatchers.IO).buffer(10)
fun main() = runBlocking {
fetchItems().collect { println("UI: $it") }
}channelFlow voor gelijktijdige producenten
channelFlow maakt een flow die door een kanaal wordt ondersteund, zodat meerdere coroutines vanuit de bouwer gelijktijdig waarden kunnen uitzenden.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun concurrentFlow(): Flow<Int> = channelFlow {
launch { send(1) }
launch { send(2) }
launch { send(3) }
}
fun main() = runBlocking {
concurrentFlow().collect { println(it) }
}De juiste strategie kiezen
Samengevat: flowOn voor het wisselen van context, buffer voor doorvoer, conflate voor alleen de nieuwste waarde in de gebruikersinterface, collectLatest voor het annuleren van verouderde verwerking.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
// Guidelines:
// CPU-heavy production -> flowOn(Dispatchers.Default)
// IO-heavy production -> flowOn(Dispatchers.IO)
// Slow consumer -> buffer()
// UI state updates -> conflate() or StateFlow
// Search/autocomplete -> collectLatest or flatMapLatest
fun main() = runBlocking { println("Choose the right strategy!") }Korte controle
Wat beïnvloedt flowOn in een flowketen?
Samenvatting
flowOn verplaatst werk stroomopwaarts naar een andere dispatcher. buffer ontkoppelt producent en consument voor een hogere doorvoer. conflate verwijdert tussenliggende waarden. collectLatest annuleert trage verwerking wanneer nieuwe waarden binnenkomen.
Leer Kotlin met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 51
- Lessen
- 203
Veelgestelde vragen
Is de les “flowOn en buffer: context en backpressure” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Kotlin Academy, waaronder “flowOn en buffer: context en backpressure”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Kotlin Academy bevat in totaal 4 lessen.
Wat leer ik in “flowOn en buffer: context en backpressure”?
Wijzig de emissiecontext met flowOn en buffer emissies voor backpressure. Je oefent met Kotlin Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Kotlin Academy te beginnen?
Ervaring vooraf is niet nodig. Kotlin Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “flowOn en buffer: context en backpressure”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Kotlin Academy?
Ja. Elke les over Kotlin Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Flow-operators: map, filter, transform en take
- catch en onCompletion: foutafhandeling in Flow
- combine en zip: meerdere Flows samenvoegen
- flowOn en buffer: context en backpressure