async — Kotlin-dagi Coroutine Builder, koroutinni ishga tushiradi va asinxron operatsiya natijasini olish uchun Deferred<T> obyektini qaytaradi. async bir nechta vazifalarni parallel bajarish va ularning natijalarini await() orqali yig'ish imkonini beradi. JetBrains, 2024 qo'llanmasiga ko'ra, async koroutinlarda parallel hisoblashlarni tashkil qilishning afzal usuli hisoblanadi.
Asosiy
async — natija qaytaruvchi koroutin yaratuvchi CoroutineScope kengaytma funksiyasidir. launch-dan farqli o'laroq, async Deferred<T> — kelajakdagi qiymatni ifodalovchi obyektni qaytaradi. async orqali ishga tushirilgan koroutin boshqa koroutinlar bilan raqobatli bajariladi, bu hisoblashlarni parallellashtirish imkonini beradi.
async asinxron operatsiya natijasi keyingi qayta ishlash uchun kerak bo'lganda ishlatiladi: bir nechta manbalardan ma'lumot yuklash, kolleksiyalarni paketli qayta ishlash, turli API-larga parallel so'rovlar. Deferred darhol yaratiladi va natija koroutin tugagandan so'ng mavjud bo'ladi.
import kotlinx.coroutines.*
suspend fun String.delayedValue(): String {
delay(1000L)
return this
}
fun main() = runBlocking {
val deferred: Deferred<String> = async { "Hello".delayedValue() }
println(deferred.await())
}
async imzosi launch-ga o'xshaydi: bir xil CoroutineContext, CoroutineStart parametrlari va suspend-blok. Farq qaytariladigan turda — Job o'rniga Deferred<T>, bu erda T blokning oxirgi ifodasi tomonidan qaytarilgan natija turidir.
public fun <T> CoroutineScope.async(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T>
Deferred<T> — Job-dan meros oluvchi va await(), getCompleted(), getCompletionExceptionOrNull() metodlarini qo'shuvchi interfeys. await() suspend-funksiya bo'lib, faqat koroutin ichida yoki boshqa suspend-funksiyada chaqirilishi mumkin. getCompleted() — bloklamaydigan metod, agar koroutin hali tugamagan bo'lsa, istisno chiqaradi.
async-ning asosiy afzalligi vazifalarni parallel ishga tushirish imkoniyatidir. Ketma-ket kutish o'rniga (umumiy vaqt = vaqtlar yig'indisi), async koroutinlarni bir vaqtda ishga tushiradi, umumiy vaqtni eng uzoq operatsiya vaqtigacha qisqartiradi.
Oddiy stsenariy — foydalanuvchi profili, sozlamalari va buyurtmalar tarixini uchta parallel async so'rovi bilan yuklash. Uchalasi tugagandan so'ng, natijalar yagona ma'lumot modelida birlashtiriladi.
suspend fun loadUserDashboard(userId: String): Dashboard = coroutineScope {
val profile = async { api.getProfile(userId) }
val settings = async { api.getSettings(userId) }
val orders = async { api.getRecentOrders(userId) }
Dashboard(
profile = profile.await(),
settings = settings.await(),
orders = orders.await()
)
}
coroutineScope funksiyasi osti koroutinlarini ishga tushiradi va natijani qaytarishdan oldin ularning tugashini kutadi. Butun blok parallel bajariladi, ketma-ket emas.
Deferred natija bilan ishlash uchun bir nechta metodlarni qo'llab-quvvatlaydi. await() bilan bir qatorda, statusni tekshirish, tayyor qiymatni olish va Kotlin Coroutines yordamchi funksiyalari orqali bir nechta Deferred-ni yig'ish metodlari mavjud.
| Metod | Tavsif | Suspend? |
|---|---|---|
| await() | Natija olinmaguncha koroutinni to'xtatadi | Ha |
| getCompleted() | Agar koroutin tugagan bo'lsa natijani qaytaradi (aks holda Exception) | Yo'q |
| getCompletionExceptionOrNull() | Xatolikda istisno yoki null qaytaradi | Yo'q |
| isCompleted | Koroutinning tugaganligini tekshiradi | Yo'q |
Deferred ro'yxatini yig'ish uchun awaitAll() — kolleksiyadagi barcha Deferred-lar tugaguncha bajarilishni to'xtatuvchi funksiya ishlatiladi. Agar kamida bittasi xato bilan tugagan bo'lsa, awaitAll() istisno chiqaradi.
suspend fun <T> loadAll(requests: List<suspend () -> T>): List<T> {
return coroutineScope {
val deferreds = requests.map { async { it() } }
deferreds.awaitAll()
}
}
async va launch o'rtasidagi tanlov koroutin bajarilishi natijasining kerakligiga bog'liq. launch Job qaytaradi va fire-and-forget operatsiyalari uchun mos keladi, async Deferred qaytaradi va ma'lumot qaytaruvchi vazifalar uchun ishlatiladi. Sintaksis va parametrlar jihatidan quruvchilar bir xil.
Muhim qoida: fire-and-forget uchun async ishlatmang. Agar koroutin natijasi kerak bo'lmasa, launch dan foydalaning. async Deferred yaratish uchun qo'shimcha yuk hosil qiladi, bu bunday stsenariyda oqlanmaydi.
Android-da async ViewModel va UseCases ichida parallel operatsiyalar uchun ishlatiladi. Oddiy stsenariylar: profil va yangiliklar lentsini bir vaqtda yuklash, bir nechta ob-havo xizmatidan ob-havo ma'lumotini olish, server bilan paketli ma'lumot sinxronizatsiyasi.
class HomeViewModel : ViewModel() {
fun loadHomeScreen() {
viewModelScope.launch {
val userData = async(Dispatchers.IO) { repository.getUserData() }
val newsFeed = async(Dispatchers.IO) { repository.getNewsFeed() }
val notifications = async(Dispatchers.IO) { repository.getNotifications() }
val state = HomeState(
user = userData.await(),
news = newsFeed.await(),
unread = notifications.await()
)
_uiState.update { state }
}
}
}
Xatolarni izolyatsiya qilish uchun async guruhini coroutineScope yoki supervisorScope bilan o'rash tavsiya etiladi. supervisorScope bir async-da xato bo'lsa ham, qolgan async koroutinlarining bajarilishini davom ettirishga imkon beradi — bu kritik bo'lmagan operatsiyalar uchun foydali.
Tez-tez beriladigan savollar
Mumkin, ammo ma'nosiz. await()siz async koroutinni ishga tushiradi, ammo natija yo'qoladi. Agar natija kerak bo'lmasa, launch dan foydalaning — u Deferred yaratmaydi va xotira hamda unumdorlik jihatidan samaraliroq.
async ichidagi istisno Deferred-da saqlanadi. await() chaqiruvi bu istisnoni uzatadi. Uzatmasdan tekshirish uchun getCompletionExceptionOrNull() dan foydalaning. coroutineScope ishlatganda, xato barcha osti koroutinlarini bekor qiladi.
awaitAll() — Iterable<Deferred<T>> uchun kengaytma funksiyasi, barcha Deferred-lar tugaguncha koroutinni to'xtatadi. Natijalar ro'yxatini qaytaradi. Agar kamida bitta Deferred xato bilan tugasa, istisno chiqaradi va qolganlarini bekor qiladi.
Ha. async — CoroutineScope kengaytma funksiyasi, scope-ga bog'langan. GlobalScope.async hayotiy tsiklga bog'lanmagan koroutin yaratadi — cheksiz bajarilishi mumkin. Android-da GlobalScope tavsiya etilmaydi, chunki xotira sizib chiqishi xavfi bor.
Son dispetcher tomonidan belgilanadi: Dispatchers.IO 64 ta bir vaqtda ishlovchi ipni qo'llab-quvvatlaydi, Dispatchers.Default — CPU yadrolari soniga qarab. Ommaviy operatsiyalar uchun Semaphore yoki mapNotNull bilan awaitAll orqali cheklangan parallellikdan foydalaning.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.