Sobes.tech
Middle

როგორ ხერხებს იცნობთ კორუტინებში შეცდომების დამუშავებისთვის?

sobes.tech AI

პასუხი AI-სგან

  • try...catch ბლოკების გამოყენება. სტანდარტული მეთოდი გამონაკლისების დამუშავებისთვის. მუშაობს კოუტინაში.

    // გამოყენება try-catch
    suspend fun fetchData(): String {
        return try {
            // ოპერაცია, რომელიც შეიძლება გამოიწვიოს გამონაკლისი
            throw Exception("მონაცემების ჩატვირთვის შეცდომა")
            "მონაცემები წარმატებით ჩატვირთულია"
        } catch (e: Exception) {
            "შეცდომა: ${e.message}"
        }
    }
    

    try...catch არ არის შესაფერისი დაუმუშავებელი გამონაკლისების დამუშავებისთვის, რომლებიც გამოიწვია შვილობილი კოუტინებიდან, რომლებიც დაიწყო სხვა CoroutineScope-ში.

  • CoroutineExceptionHandler. იჭერს დაუმუშავებელ გამონაკლისებს, რომლებიც გამოიწვია კოუტინები, რომლებიც დაიწყო ამ CoroutineScope-ში ან მის შვილობილ CoroutineScope-ებში.

    // CoroutineExceptionHandler
    val handler = CoroutineExceptionHandler { _, exception ->
        println("დამჭერილი გამონაკლისი: $exception")
    }
    
    // გამოყენება CoroutineExceptionHandler-ის
    GlobalScope.launch(handler) {
        // კოუტინა, რომელიც შეიძლება გამოიწვიოს გამონაკლისი
        throw Exception("კოუტინაში შეცდომა")
    }
    

    CoroutineExceptionHandler აქტივირდება მხოლოდ იმ გამონაკლისებისთვის, რომლებიც არ დამუშავებულა სტრუქტურირებული კონკურენციის მექანიზმით.

  • SupervisorJob და supervisorScope. განსხვავდება ჩვეულებრივი Job-ისგან, როდესაც შვილობილი კოუტინა შეცდომის გამო იწვევს მშობლის Job-ის გაუქმებას, SupervisorJob-ი ამას არ აკეთებს. supervisorScope ქმნის CoroutineScope-ს SupervisorJob-ით.

    // გამოყენება supervisorScope-ის
    suspend fun loadMultipleData() = supervisorScope {
        val data1 = async {
            // შეიძლება გამოიწვიოს გამონაკლისი
            throw Exception("შეცდომა მონაცემებში 1")
            "მონაცემები 1"
        }
        val data2 = async {
            "მონაცემები 2"
        }
    
        // შეიძლება დამუშავდეს გამონაკლისი კონკრეტული async-ისთვის
        try {
            println("შედეგი 1: ${data1.await()}")
        } catch (e: Exception) {
            println("შეცდომა მონაცემების ჩატვირთვაში 1-ით: ${e.message}")
        }
        println("შედეგი 2: ${data2.await()}")
    }
    

    ეს გამოიყენება დამოუკიდებელი შვილობილი დავალებებისთვის, სადაც ერთი შეცდომა არ უნდა გავლენას ახდენდეს სხვაებზე. არ ცვლის try...catch ან CoroutineExceptionHandler, არამედ იცვლის გამონაკლისების გავრცელების ქცევას.

  • სტრუქტურირებული კონკურენციის დროს გამონაკლისების გავრცელება. დეფოლტად, შვილობილი კოუტინაში გამონაკლისი იწვევს მშობლის კოუტინას და მის სიბლინგებს გაუქმებას.

    // გამონაკლისის გავრცელების მაგალითი
    runBlocking {
        val job = launch {
            launch { // შვილობილი 1
                delay(100)
                throw Exception("შვილობილი 1-ში შეცდომა")
            }
            launch { // შვილობილი 2
                delay(200)
                println("შვილობილი 2 დასრულდა")
            }
        }
        try {
            job.join()
        } catch (e: Exception) {
            println("გათვალისწინებული გამონაკლისი მშობელში: $e")
        }
    }
    

    ეს არის სტრუქტურირებული კონკურენციის ძირითადი ქცევა, რომელიც ეხმარება რესურსების და მდგომარეობების გაჟონვის თავიდან აცილებას.

  • გამოყენება async და await()-თან. async-ში გამოყოფილი გამონაკლისები ავტომატურად არ გავრცელდება. ისინი ინახება Deferred-ში და გამოიწვევიან მხოლოდ await()-ის დროს.

    // გამონაკლისების დამუშავება async/await-ით
    suspend fun safeAsyncCall() = coroutineScope {
        val deferred = async {
            throw Exception("შეცდომა async-ში")
            "Async-ის შედეგი"
        }
    
        try {
            val result = deferred.await()
            println("შედეგი: $result")
        } catch (e: Exception) {
            println("გამონაკლისი async-დან: ${e.message}")
        }
    }
    

    ეს საშუალებას აძლევს არჩევით დამუშავება შეცდომების თითოეულ ასინქრონულ დავალებაზე.

მეთოდი დანიშნულება დამუშავებს დაუმუშავებელს? იცვლება გავრცელება?
try...catch შეცდომების დამუშავება მიმდინარე კოუტინაში არა არა
CoroutineExceptionHandler დაუმუშავებელი შეცდომების დამჭერი Scope-ში კი არა
SupervisorJob/Scope გავრცელების ქცევის შეცვლა არა კი
სტრუქტურირებული კონკურენცია ავტომატური გაუქმება შეცდომის დროს კი კი
async + await() დაგეგმილი გავრცელება შეცდომის არა კი (მდე await)