Sobes.tech
Middle

Flow'da qanday qilib oqimlarni o'tkazish mumkin? Flow qaysi oqimda ishlaydi?

sobes.tech AI

AIdan javob

Odatda Flow ishlash uchun boshlang'ich oqimda ishlaydi. flowOn operatori yordamida oqimni o'zgartirish mumkin.

import kotlinx.coroutines.CoroutineDispatcher // CoroutineDispatcher uchun
import kotlinx.coroutines.Dispatchers // Dispatchers uchun
import kotlinx.coroutines.flow.Flow // Flow uchun
import kotlinx.coroutines.flow.flow // flow uchun
import kotlinx.coroutines.flow.flowOn // flowOn uchun
import kotlinx.coroutines.runBlocking // runBlocking uchun

// Flow qaytaradigan funksiyaning misoli
fun simpleFlow(): Flow<Int> = flow {
    logThread("Flow boshlang'ich") // flow builder ishlayotgan threadni log qilish
    for (i in 1..3) {
        emit(i) // Qiymatlarni chiqarish
    }
}

fun main() = runBlocking {
    simpleFlow()
        .flowOn(Dispatchers.IO) // Upstream (emitterlar) Dispatchers.IO ga o'tkaziladi
        .collect { value ->
            logThread("To'plangan $value") // Qiymatlar to'planayotgan threadni log qilish
        }
}

// Threadni log qilish uchun yordamchi funksiya
fun logThread(msg: String) {
    println("[$msg] [${Thread.currentThread().name}]")
}

flowOn operatori, u bilan bog'langan operatsiyalar oldin bajariladigan threadga ta'sir qiladi (shu jumladan flow builder). flowOndan keyin keladigan operatsiyalar, flowOn argumentida ko'rsatilgan threadda bajariladi. Agar ketma-ketlikda bir nechta flowOn bo'lsa, har biri o'zidan oldingi qismga ta'sir qiladi.

Bir nechta flowOn bilan misol:

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking

fun simpleFlowWithMultipleFlowOn(): Flow<String> = flow {
    logThread("Flow builder boshlang'ich") // Birinchi `flowOn`da ishlaydi
    emit("A")
    emit("B")
}.map {
    logThread("Mapping $it") // Ikkinchi `flowOn`da ishlaydi
    it.toLowerCase()
}.flowOn(Dispatchers.Default) // Ikkinchi `flowOn` map() va flow builderga ta'sir qiladi
.filter {
    logThread("Filtering $it") // `collect` chaqirilgan threadda ishlaydi (odatda main/runBlocking)
    true
}.flowOn(Dispatchers.IO) // Birinchi `flowOn` map() va flow builderga ta'sir qiladi

fun main() = runBlocking {
    simpleFlowWithMultipleFlowOn().collect { value ->
        logThread("To'plangan $value") // runBlocking (main) threadda ishlaydi
    }
}

fun logThread(msg: String) {
    println("[$msg] [${Thread.currentThread().name}]")
}

Bu misolda:

  • flow builder va map Dispatchers.Defaultda ishlaydi (chunki bu oxirgi flowOn ular oldidan keladi).
  • filter collect chaqirilgan threadda ishlaydi, ya'ni runBlocking bajariladigan threadda (odatda Main Androidda).

Muhim: flowOn oraliq bufer yaratadi va "transparant" thread o'zgarishi emas.