Sobes.tech
Middle

Kādus kļūdu apstrādes veidus jūs zināt korutīnās?

sobes.tech AI

Atbilde no AI

  • Izmantot try...catch blokus. Standarta izņēmumu apstrādes veids. Darbojas korutinas iekšienē.

    // Izmantojot try-catch
    suspend fun fetchData(): String {
        return try {
            // Operācija, kas var izraisīt izņēmumu
            throw Exception("Kļūda ielādējot datus")
            "Dati veiksmīgi ielādēti"
        } catch (e: Exception) {
            "Kļūda: ${e.message}"
        }
    }
    

    try...catch nav piemērots neapstrādātu izņēmumu apstrādei, kurus izmet bērnu korutinas, kas palaistas citā CoroutineScope.

  • CoroutineExceptionHandler. Noķer neapstrādātus izņēmumus, kurus izmet korutinas, kas palaistas šajā CoroutineScope vai tā bērnu CoroutineScope.

    // CoroutineExceptionHandler
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Noķerta izņēmuma kļūda: $exception")
    }
    
    // Izmantojot CoroutineExceptionHandler
    GlobalScope.launch(handler) {
        // Korutina, kas var izraisīt izņēmumu
        throw Exception("Kļūda korutīnā")
    }
    

    CoroutineExceptionHandler darbojas tikai neapstrādātiem izņēmumiem, kas netiek apstrādāti ar strukturētas konkurences mehānismu.

  • SupervisorJob un supervisorScope. Atšķirībā no parasta Job, ja bērna korutina ar kļūdu izraisa vecāka Job atcelšanu, SupervisorJob to nedara. supervisorScope izveido CoroutineScope ar SupervisorJob.

    // Izmantojot supervisorScope
    suspend fun loadMultipleData() = supervisorScope {
        val data1 = async {
            // Var izraisīt izņēmumu
            throw Exception("Kļūda datos 1")
            "Dati 1"
        }
        val data2 = async {
            "Dati 2"
        }
    
        // Var apstrādāt izņēmumu konkrētajā `async`
        try {
            println("Rezultāts 1: ${data1.await()}")
        } catch (e: Exception) {
            println("Kļūda ielādējot datus 1: ${e.message}")
        }
        println("Rezultāts 2: ${data2.await()}")
    }
    

    Izmanto neatkarīgām bērnu uzdevumiem, kur viena kļūda nedrīkst ietekmēt citas. Neko maina ar try...catch vai CoroutineExceptionHandler, bet maina izplatīšanās uzvedību.

  • Izplatīšanās struktūrizētajā konkurencē. Pēc noklusējuma, bērna korutinas izņēmums atceļ vecāka korutinu un visus tās brāļus.

    // Piemērs, kā izplatās izņēmums
    runBlocking {
        val job = launch {
            launch { // Bērna korutina 1
                delay(100)
                throw Exception("Kļūda bērna 1")
            }
            launch { // Bērna korutina 2
                delay(200)
                println("Bērna 2 izpildījās")
            }
        }
        try {
            job.join()
        } catch (e: Exception) {
            println("Izņēmums noķerts vecākajā: $e")
        }
    }
    

    Šis ir pamata struktūrizētas konkurences uzvedība, kas palīdz izvairīties no resursu un stāvokļu noplūdēm.

  • Izmantojot async ar await(). Izņēmumi, kas izmet async, _ne_izplatās automātiski. Tie tiek glabāti Deferred un izmetami tikai, izsaucot await().

    // Izņēmumu apstrāde ar async/await
    suspend fun safeAsyncCall() = coroutineScope {
        val deferred = async {
            throw Exception("Kļūda async")
            "Async rezultāts"
        }
    
        try {
            val result = deferred.await()
            println("Rezultāts: $result")
        } catch (e: Exception) {
            println("Noķerta izņēmuma no async: ${e.message}")
        }
    }
    

    Tas ļauj izvēles kārtā apstrādāt kļūdas katrai asinhronajai uzdevumam.

Veids Mērķis Apstrādā neapstrādātas? Maina izplatīšanos?
try...catch Išimčių apstrāde iekšējā korutinā
CoroutineExceptionHandler Neapstrādātu izņēmumu noķeršana Scope'ā
SupervisorJob/Scope Izplatīšanās uzvedības maiņa
Struktūrizēta konkurence Automātiska atcelšana kļūdas gadījumā
async + await() Atliektā izplatīšanās no izņēmuma Jā (pirms await)