Coroutines: suspend, scope, dispatcher-lər
Coroutine — dayandırıla bilən (suspendable) hesablama vahididir: thread-i bloklamadan gözləyə bilir. Bir thread minlərlə coroutine icra edə bilər.
Əsas anlayışlar:
- suspend fun — dayandırıla bilən funksiya; yalnız coroutine içindən və ya başqa suspend funksiyadan çağırılır.
suspendözü thread dəyişmir — sadəcə dayanma nöqtəsi verir. - CoroutineScope — coroutine-lərin həyat dövrünü idarə edir. Android-də hazır scope-lar:
viewModelScope,lifecycleScope. - Job — coroutine-in ləğv edilə bilən dəstəyi; SupervisorJob — bir uşağın xətası qardaşlarını ləğv etmir.
- Dispatchers:
Main(UI),IO(şəbəkə/disk),Default(CPU-intensiv hesablama). - structured concurrency — hər coroutine bir scope-a bağlıdır: scope ləğv olunanda bütün uşaqlar da ləğv olunur, "itmiş" coroutine qalmır.
kotlin
class AccountViewModel(private val repo: AccountRepository) : ViewModel() {
fun loadBalance() {
viewModelScope.launch { // Main dispatcher-də başlayır
_uiState.update { it.copy(isLoading = true) }
try {
val balance = withContext(Dispatchers.IO) {
repo.fetchBalance() // şəbəkə çağırışı IO thread pool-da
}
_uiState.update { it.copy(balance = balance, isLoading = false) }
} catch (e: IOException) {
_uiState.update { it.copy(error = "Şəbəkə xətası", isLoading = false) }
}
}
}
}ViewModel-də tipik pattern: IO işi, Main-də nəticə
| Sual | launch | async |
|---|---|---|
| Nə qaytarır | Job (nəticəsiz) | Deferred<T> — await() ilə nəticə |
| Nə üçün | "Fire and forget" iş | Paralel hesablamaların nəticələri |
| Exception davranışı | Dərhal parent-ə ötürülür | await() çağırılana qədər saxlanılır |
Cancellation kooperativdir: coroutine yalnız suspension nöqtələrində (delay, withContext, yield) və ya isActive yoxlamasında ləğvi "görür". Sonsuz while(true) dövrü suspension nöqtəsi olmadan ləğv olunmur. CancellationException-ı udmaq (catch edib ötürməmək) klassik bug-dır — onu həmişə yenidən at.
🛠 Tapşırıq
Balans və tranzaksiya tarixçəsini "çəkən" iki suspend funksiya yaz (hər biri delay(1500) ilə imitasiya).
- Əvvəl ardıcıl çağır, vaxtı ölç (
measureTimeMillis). - Sonra
async+awaitilə paralel çağır, vaxtı yenidən ölç. - Birində exception at və
launchiləasyncarasındakı davranış fərqini gör.
Bitdi sayılır: ~3s → ~1.5s fərqini və exception davranışını izah edə bilirsənsə.
📚 Mənbələr və sənədlər
- Coroutines icmalı — Kotlin sənədlərirəsmikotlinlang.org
- Android-də coroutinesrəsmideveloper.android.com
- Coroutines best practices — Androidrəsmideveloper.android.com