Middle
Kuidas saab Flow'ss voogusid vahetada? Millises voos töötab Flow?
sobes.tech AI
Vastus AI-lt
Vaikimisi Flow töötab selle vooga, millest see käivitati. Voodite vahetamiseks saab kasutada flowOn operaatorit.
import kotlinx.coroutines.CoroutineDispatcher // CoroutineDispatcher jaoks
import kotlinx.coroutines.Dispatchers // Dispatchers jaoks
import kotlinx.coroutines.flow.Flow // Flow jaoks
import kotlinx.coroutines.flow.flow // flow jaoks
import kotlinx.coroutines.flow.flowOn // flowOn jaoks
import kotlinx.coroutines.runBlocking // runBlocking jaoks
// Näidissüsteem, mis tagastab Flow
fun simpleFlow(): Flow<Int> = flow {
logThread("Flow algas") // Logimine voog, kus käivitatakse flow builder
for (i in 1..3) {
emit(i) // Väärtuste saatmine
}
}
fun main() = runBlocking {
simpleFlow()
.flowOn(Dispatchers.IO) // Ülemise (emitters) voogedastuse vahetamine Dispatchers.IO-ks
.collect { value ->
logThread("Kogutud $value") // Logimine voog, kus väärtused kogutakse
}
}
// Abi funktsioon voogude logimiseks
fun logThread(msg: String) {
println("[$msg] [${Thread.currentThread().name}]")
}
flowOn operaator mõjutab voogu, kus operatsioonid enne seda (sh flow builder). Pärast flowOn toimuvad operatsioonid sellel niidil, mis on näidatud flowOn argumentides. Kui on mitu flowOn, siis igaüks neist mõjutab oma osa enne seda.
Näide mitme flowOn-ga:
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
fun simpleFlowWithMultipleFlowOn(): Flow<String> = flow {
logThread("Flow builder algas") // Töötab esimese määratud `flowOn`-ga
emit("A")
emit("B")
}.map {
logThread("Kaardistamine $it") // Töötab teise määratud `flowOn`-ga
it.toLowerCase()
}.flowOn(Dispatchers.Default) // Teine `flowOn` mõjutab `map` ja `flow` builderit
.filter {
logThread("Filtreerimine $it") // Töötab `collect`-i välise voogena (tavaliselt main/runBlocking)
true
}.flowOn(Dispatchers.IO) // Esimene `flowOn` mõjutab `map` ja `flow` builderit
fun main() = runBlocking {
simpleFlowWithMultipleFlowOn().collect { value ->
logThread("Kogumine $value") // Töötab `runBlocking`-i vooges (main)
}
}
fun logThread(msg: String) {
println("[$msg] [${Thread.currentThread().name}]")
}
Selles näites:
flowbuilder jamaptöötavadDispatchers.Default-is (sest see on viimaneflowOnnende ees).filtertöötab vooges, milleltcollectkutsutakse, see tähendabrunBlocking-i vooges (tavaliselt Main Androidis).
Oluline on mõista, et flowOn loob vahekiibi ja ei ole "läbipaistev" vahetus.