Middle
Kā var pārslēgt plūsmas Flow? Kurā plūsmas daļā darbojas Flow?
sobes.tech AI
Atbilde no AI
Pēc noklusējuma Flow darbojas tajā pavedienā, no kura tas tika palaists. Pavedienu pārslēgšanu var veikt ar operatoru flowOn.
import kotlinx.coroutines.CoroutineDispatcher // Par CoroutineDispatcher
import kotlinx.coroutines.Dispatchers // Par Dispatchers
import kotlinx.coroutines.flow.Flow // Par Flow
import kotlinx.coroutines.flow.flow // Par flow
import kotlinx.coroutines.flow.flowOn // Par flowOn
import kotlinx.coroutines.runBlocking // Par runBlocking
// Piemēra funkcija, kas atgriež Flow
fun simpleFlow(): Flow<Int> = flow {
logThread("Flow sāka darboties") // Žurnāla izvadīšana pavedienā, kur sākas flow būvētājs
for (i in 1..3) {
emit(i) // Vērtību emitēšana
}
}
fun main() = runBlocking {
simpleFlow()
.flowOn(Dispatchers.IO) // Pārsūtām augšējo (emitētājus) uz Dispatchers.IO
.collect { value ->
logThread("Savākti $value") // Žurnāla izvadīšana pavedienā, kur tiek savāktas vērtības
}
}
// Palīdzības funkcija žurnāla izvadīšanai
fun logThread(msg: String) {
println("[$msg] [${Thread.currentThread().name}]")
}
Operator flowOn ietekmē pavedienu, kurā tiek izpildīti operatori pirms tā (ieskaitot flow būvētāju). Operatori pēc flowOn tiek izpildīti uz pavediena, kas norādīts flowOn argumentā. Ja ir vairāki flowOn, katrs ietekmē savu daļu pirms tā.
Piemērs ar vairākiem flowOn:
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
fun simpleFlowWithMultipleFlowOn(): Flow<String> = flow {
logThread("Flow būvētājs sāka darboties") // Darbojas uz pirmā norādītā `flowOn`
emit("A")
emit("B")
}.map {
logThread("Kartēšana $it") // Darbojas uz otra norādītā `flowOn`
it.toLowerCase()
}.flowOn(Dispatchers.Default) // Otra `flowOn` ietekmē uz `map` un `flow` būvētāju
.filter {
logThread("Filtrēšana $it") // Darbojas uz pavediena, no kura izsauc `collect` (parasti maina/runBlocking)
true
}.flowOn(Dispatchers.IO) // Pirmais `flowOn` ietekmē uz `map` un `flow` būvētāju
fun main() = runBlocking {
simpleFlowWithMultipleFlowOn().collect { value ->
logThread("Vāko $value") // Darbojas uz `runBlocking` pavediena (main)
}
}
fun logThread(msg: String) {
println("[$msg] [${Thread.currentThread().name}]")
}
Šajā piemērā:
flowbūvētājs unmapdarbosies uzDispatchers.Default(jo tas ir pēdējaisflowOnķēdē pirms tiem).filterdarbosies uz pavediena, no kura tiek izsauktscollect, tas ir, uzrunBlockingpavediena (parasti galvenais Android).)
Svarīgi saprast, ka flowOn rada starpposma buferi un nav "caurspīdīgs" pārslēgums.