Корутинада кандайча иш болот, эгерде ката чыкса?
sobes.tech AI
AIден жооп
Корутина ичинде чыккан кырдаалда, кырдаалдын түрүнө (жана dispatcher/контексттин орнотууларына) жараша, аны кантип иштетүү керектиги аныкталат.
-
Бекемделбеген кырдаал: Эгер кырдаал корутина ичинде кармалбаса, ал корутиндердин хиерархиясы аркылуу эң жакын
Job(жеCoroutineScope) чейин жогору көтөрүлөт. Анын жүрүм-турумуJobтин түрүнө жараша болот:Job: Төлөмдө, эгерде балдар корутинада кырдаал пайда болсо, ата-эненинJobи токтотулат, бул анын калган балдар корутиндерин да токтотот. Кырдаал жогору көтөрүлөт.SupervisorJob:SupervisorJobкырдаал пайда болгондо токтотулбайт. Тек гана кырдаал чыккан корутина токтотулат. Бул бир баланын токтотулушу башка балдарга таасир этпеши керек болгон учурда пайдалуу.CoroutineScopeнегизги: Эгер кырдаалCoroutineScopeнегизине (мисалы,GlobalScopeжеCoroutineScopeаркылуу түзүлгөнJobсиз scope) жетсе, алCoroutineExceptionHandlerглобалдык иштетүүчүгө өткөрүлөт. Төлөмдө, эгер иштетүүчү катталбаса, кырдаалSystem.errке жазылат.
-
Кармалган кырдаал: Эгер кырдаал
try-catchблогу аркылуу корутина ичинде кармалса, ал жергиликтүү иштетилет жана корутинаcatchблогунан кийин уланат, эгер мүмкүн болсо. Кырдаал жогору көтөрүлбөйт. -
Токтотуу менен байланышкан кырдаалдар (мисалы,
CancellationException): Бул кырдаалдар өзгөчө. Алар корутиндердин токтотуу механизми үчүн колдонулат жана көбүнчө иштетүүчүлөр тарабынан көз жаздымда калтырылат. АларJobтин фаталдуу каталыгына алып келбейт. -
asyncичинде кырдаалдар:asyncаркылуу ишке киргизилген корутина өзүнүнDeferredобъектине кырдаалды жайгаштырат. КырдаалDeferred.await()чакырылганда гана өткөрүлөт. Башка учурда, ал "жашырын" калат.
import kotlinx.coroutines.*
fun main() = runBlocking {
val scope = CoroutineScope(SupervisorJob())
scope.launch {
try {
println("Корутина 1 башталды")
delay(100)
throw RuntimeException("Корутина 1 ичинде ката чыкты")
} catch (e: Exception) {
println("Корутина 1 ичинде кармалган кырдаал: ${e.message}")
}
}
scope.launch {
println("Корутина 2 башталды")
delay(500)
println("Корутина 2 аяктады")
}
delay(1000) // Натыйжаны көрүү үчүн күтүп жатабыз
scope.cancel() // scopeти токтотуу
}
Бул мисалда, Корутина 1 ичиндеги кырдаал кармалган жана Корутина 2 ишин улантат, анткени SupervisorJob колдонулган. Эгер Job колдонулса, анда Корутина 1 ичиндеги кырдаал Корутина 2нин токтотулушуна алып келет.