Sobes.tech
Middle

Kotlin, asinxron əməliyyatlarla işləmək üçün hansı imkanları təqdim edir?

sobes.tech Süni İntellekt

AI-dan cavab

Kotlin asinxron əməliyyatları sadələşdirmək üçün korutinlər (coroutines) təqdim edir və yüngül çəkili axınlar təklif edir ki, bunlar əsas icra axını bloklamır.

Əsas imkanlar:

  • Dayanma funksiyaları: suspend açar sözü ilə işarələnmiş funksiyalar, dayandırıla və davam etdirilə bilər. Onlar icra olunan axını bloklamır.
    suspend fun fetchData(): String {
        delay(1000) // Uzun əməliyyatı təqlid edir
        return "Məlumat alındı"
    }
    
  • Korutin qurucuları: Korutinləri başlatmaq üçün istifadə olunan funksiyalar:
    • launch: Yeni korutin başlatır və Job qaytarır (bloklamaz).
      GlobalScope.launch {
          println("Korutin başladı")
      }
      
    • async: Yeni korutin başlatır və Deferred<T> qaytarır (.await() çağırışında bloklayıcıdır).
      val deferred = GlobalScope.async {
          fetchData()
      }
      // ...
      val result = deferred.await() // Nəticəni gözləyir
      
    • runBlocking: Cari axını bloklayır və korutinin tamamlanmasını gözləyir (əsasən, bloklayan və qeyri-bloklayan kodlar arasında körpü üçün istifadə olunur, məsələn, testlərdə).
      runBlocking {
          val data = fetchData()
          println(data)
      }
      
  • CoroutineContext: Korutinin davranışını müəyyən edən elementlər toplusu, o cümlədən DispatcherJob.
    • Dispatcher: Korutinin icra olunduğu axın və ya axın hovuzunu müəyyən edir.
  • Dispatchers: İstifadə olunan obyektlər:
    • Dispatchers.Default: Ümumi fon axın hovuzu.
    • Dispatchers.IO: Giriş/çıxış üçün optimallaşdırılmışdır (disk və şəbəkə əməliyyatları).
    • Dispatchers.Main: UI-nin əsas axını (Android, JavaFX və s. üçün).
    • Dispatchers.Unconfined: Korutini cari axında işə salır, lakin dayandırıldıqdan sonra hər hansı bir axında davam edə bilər.
    GlobalScope.launch(Dispatchers.IO) {
        // Giriş/çıxış axınında icra olunur
    }
    
  • Structured Concurrency: Prinsipə görə, korutinlər valideyn (CoroutineScope) ilə idarə olunur və valideyn ləğv olunduqda, onlar da avtomatik olaraq ləğv edilir. Bu, resurs sızmalarını qarşısını alır və həyat dövrünün idarə olunmasını asanlaşdırır.
    // CoroutineScope avtomatik olaraq uşaqlarını idarə edir
    val scope = CoroutineScope(Dispatchers.Default)
    val job = scope.launch {
        // ...
    }
    // scope ləğv olunduqda, bütün uşaqlar da ləğv edilir
    scope.cancel()
    
  • Channels: Korutinlər arasında təhlükəsiz məlumat ötürülməsi üçün kanallar. Onlar:
    • Unbuffered: Yalnız göndərildikdən sonra qəbul edilir.
    • Buffered: Bir neçə elementi göndərməyə imkan verir, bloklama olmadan.
    • Conflated: Yalnız son göndərilən elementi saxlayır.
    val channel = Channel<Int>()
    
    scope.launch {
        for (x in 1..5) channel.send(x)
        channel.close()
    }
    
    scope.launch {
        for (y in channel) println(y)
    }
    
  • Flow: Bir neçə dəyəri asinxron şəkildə yayımlaya bilən məlumat axını. RxJava Observable-a bənzəyir, lakin daha yüngüldür və korutinlərlə inteqrasiya olunub.
    fun simpleFlow(): Flow<Int> = flow {
        for (i in 1..3) {
            delay(100)
            emit(i) // Dəyəri göndərir
        }
    }
    
    runBlocking {
        simpleFlow().collect { value -> println(value) } // Dəyərləri qəbul edir
    }
    

Bu imkanlar, asinxron kodu imperativ tərzdə yazmağa imkan verir və onu daha oxunaqlı və dəstəklənən edir, callback və ya Future istifadə etməklə müqayisədə.