Ի՞նչ է տեղի ունենում կորուտինայի հետ, երբ տեղի է ունենում արտահայտություն։
sobes.tech AI
Պատասխան AI-ից
Երբ տեղի է ունենում արտակարգ իրավիճակ՝ ներսում կորուտինում, կախված արտակարգ իրավիճակի տեսակից (և dispatcher/կոնտեքստի կարգավորումներից), որոշվում է, թե ինչպես այն կթարգմանվի։
-
Անհետաձգելի արտակարգ իրավիճակ: Եթե արտակարգ իրավիճակը չհավաքվի ներսում կորուտինում, այն բարձրանում է կորուտինների հիերարխիայով մինչև ամենամոտ
Job(կամCoroutineScope)։ Կարգավորումը կախված էJobտեսակից.Job: Դեպքում, երբ արտակարգ իրավիճակ է առաջանում դուստր կորուտինում, ծնողականJob-ը չեղյալ է հայտարարվում, ինչը հանգեցնում է նրա մյուս դուստր կորուտինների չեղյալ հայտարարմանը։ Արտակարգ իրավիճակը փոխանցվում է վերև։SupervisorJob:SupervisorJob-ը չի չեղյալ հայտարարվում արտակարգ իրավիճակի դեպքում դուստր կորուտինում։ Միայն այն կորուտինն է չեղյալ հայտարարվում, որտեղ արտակարգ իրավիճակ է տեղի ունեցել։ Սա օգտակար է, երբ անհրաժեշտ է, որ մեկ դուստր գործի չեղյալ հայտարարման դեպքում մյուսները շարունակեն գործել։CoroutineScope-ի հիմքը: Եթե արտակարգ իրավիճակը հասնում էCoroutineScope-ին (օրինակ,GlobalScopeկամCoroutineScope-ով ստեղծված առանցJob), այն փոխանցվում էCoroutineExceptionHandler-ին։ Դեպքում, երբ չի գրանցված handler, արտակարգ իրավիճակը գրանցվում էSystem.err-ում։
-
Հավաքված արտակարգ իրավիճակ: Եթե արտակարգ իրավիճակը բռնվում է
try-catchբլոկով կորուտինում, այն տեղական է և կորուտինան շարունակում է գործելcatch-ից հետո, եթե դա հնարավոր է։ Արտակարգ իրավիճակը չի փոխանցվում վերև։ -
Արտակարգ իրավիճակներ, կապված չեղարկման հետ (օրինակ,
CancellationException): Այս արտակարգ իրավիճակները հատուկ են։ Դրանք օգտագործվում են կորուտինների չեղարկման մեխանիզմի համար և սովորաբար անտեսվում են արտակարգ իրավիճակների մշակողներից շատերի կողմից։ Դրանք չեն հանգեցնումJob-ի ֆատալային ձախողման։ -
async-ի մեջ արտակարգ իրավիճակներ:async-ով սկսված կորուտինը տեղադրում է արտակարգ իրավիճակը իր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-ի չեղարկմանը։