Asenkron oqimlar Asinxron oqimlarga kirish
Koroutinlar bitta qiymatlarni qaytarishga imkon beradi. Buni amalga oshirish uchun, masalan, async builder yordamida koroutin yaratishimiz mumkin . Ammo Kotlin sizga ob'ektlar to'plamini qaytaradigan asinxron oqimlarni yaratishga imkon beradi.
Printsipial jihatdan, ob'ektlar to'plamini olish uchun biz elementlar to'plamini korutinda qaytarishimiz mumkin, masalan, List kabi:
1
2018-05-01 xoxlasa buladi 121 2
3
4
5
6
7
sakkiz
to'qqiz
o'n
o'n bir
12
13
|
import kotlinx.coroutines.*
suspend fun main() = coroutineScope{
launch {
getUsers().forEach { user -> println(user) }
}
}
suspend fun getUsers(): List {
delay(1000L) // имитация продолжительной работы
return listOf("Tom", "Bob", "Sam")
}
|
Biroq, bunday to'plamlarning muammosi shundaki, ular bir vaqtning o'zida barcha ob'ektlarni qaytaradilar. Masalan, agar ro'yxatda 1000 ta ob'ekt kutilsa, demak, funktsiya getUsers() 1000 ta ob'ektlar ro'yxatini qaytarguncha (masalan, ularni ma'lumotlar bazasidan yoki tashqi Internet -resursdan olish) biz ob'ektlarni boshqara olmaymiz. bu ro'yxatdan.
Kotlindagi bu muammo asinxron oqimlar hal qila oladigan narsadir. Yuqoridagi misolni asinxron oqimlar yordamida o'zgartiramiz:
1
2018-05-01 xoxlasa buladi 121 2
3
4
5
6
7
sakkiz
to'qqiz
o'n
o'n bir
12
13
o'n to'rt
15
16
|
import kotlinx.coroutines.flow.*
suspend fun main(){
getUsers().collect { user -> println(user) }
}
fun getUsers(): Flow = flow {
val database = listOf("Tom", "Bob", "Sam") // условная база данных
var i = 1;
for (item in database){
delay(400L) // имитация продолжительной работы
println("Emit $i item")
emit(item) // емитируем значение
i++
}
}
|
Asenkron ma'lumotlar oqimini yaratish uchun Flow interfeysi ishlatiladi . Ya'ni, mohiyatan, asinxron oqim - Flow ob'ektidir. U oqimda uzatiladigan ma'lumotlar turiga ko'ra yoziladi. Bunday holda, biz satrlarni o'tkazamiz, shuning uchun u Flowturiga ko'ra yoziladi String.
Bunday holda, funktsiya-oqimni (bu holda, funktsiyani getUsers) belgilashda to'xtatib turuvchi modifikatorni ishlatish shart emas .
Flow ob'ektini yaratish uchun flow () maxsus funktsiyasidan foydalaning.
1
2018-05-01 xoxlasa buladi 121 2
3
4
|
fun getUsers(): Flow = flow {
// создание асинхронного потока в функции flow
}
|
Funktsiyaning o'zida, bu holda shartli ma'lumotlar bazasidan ob'ektlarni olish simulyatsiya qilinadi, bu erda soddalik uchun Ro'yxat. Bir tsiklda biz ushbu ro'yxatni ko'rib chiqamiz va joriy ob'ektni emit () funktsiyasidan foydalanib oqimga yuboramiz :
1
|
emit(item) // передаем значение в поток
|
Bu asosiy nuqta. Buning yordamida tashqi kod emit()oqim orqali o'tgan qiymatni olishi va undan foydalanishi mumkin bo'ladi.
Yuborilayotgan ob'ektning raqamini ko'rsatish uchun men iro'yxatdagi boshqa ob'ektga o'tishda ko'payadigan hisoblagich o'zgaruvchisini qo'shdim. Yuborilayotgan ob'ektning raqamini ko'rsatish orqali siz tashqi kod ro'yxatdagi ob'ektlarni funktsiyadan foydalanib oqimga uzatilganda qabul qilishini ko'rishingiz mumkin, ro'yxatdagi emit()barcha ob'ektlar yuborilganda emas.
Tashqi kodda, asosiy funktsiyada biz ip funksiyasini chaqiramiz getUsers(). Oqimdagi ob'ektlarni manipulyatsiya qilish uchun Flow interfeysi uchun bir qator funksiyalar aniqlanadi, ulardan biri funktsiyadir collect(). Parametr sifatida u chiqadigan ob'ektni oqimdan uzatadigan funktsiyani qabul qiladi. Shunday qilib, bu holda, bu faqat konsol chiqish funktsiyasi:
1
|
getUsers().collect { user -> println(user) }
|
Natijada biz quyidagi konsol chiqishini olamiz:
1 ta elementni chiqaring
Tom
2 ta elementni chiqaring
Bob
3 ta elementni chiqaring
Sem
Shunday qilib, dastur getUsers funksiyasi barcha qatorlarni qaytarishini kutmaydi. Va u funksiya orqali oqimga yuborilganda satrlarni oladi emit().
Yana bir misol - keling, asinxron raqamlar oqimini yaratamiz va ishlatamiz:
1
2018-05-01 xoxlasa buladi 121 2
3
4
5
6
7
sakkiz
to'qqiz
o'n
o'n bir
|
import kotlinx.coroutines.flow.*
suspend fun main(){
getNumbers().collect { number -> println(number) }
}
fun getNumbers(): Flow = flow{
for(item in 1..5){
emit(item * item)
}
}
|
Bu erda, printsipial jihatdan, hamma narsa bir xil. Funktsiya getNumbers()Int ob'ektlarining asenkron oqimini ifodalaydi. Oqimga obyekt sifatida 1 dan 5 gacha bo‘lgan raqamlar kvadratlari qo‘shiladi.Dasturning konsolli chiqishi:
1
4
to'qqiz
16
25
Do'stlaringiz bilan baham: |