Sobes.tech
Middle

Ի՞նչ հնարավորություններ է առաջարկում Kotlin-ը ասինխրոնային օպերացիաներով աշխատելու համար։

sobes.tech AI

Պատասխան AI-ից

Կոտլինը առաջարկում է կորուտիններ (coroutines)՝ ասինխրոնային գործողությունները պարզեցնելու համար, առաջարկելով թեթև հոսքեր, որոնք չեն բլոկավորում հիմնական կատարողական հոսքը:

Հիմնական հնարավորությունները՝

  • Հետաձգման ֆունկցիաներ: suspend բանալի բառով նշված ֆունկցիաները, որոնք կարող են հետաձգվել և շարունակվել: Դրանք չեն բլոկավորում կատարման հոսքը:
    suspend fun fetchData(): String {
        delay(1000) // Դիտարկում երկար գործողություն
        return "Տվյալները ստացվել են"
    }
    
  • Կորուտինների կառուցապատողներ: Ֆունկցիաներ, որոնք օգտագործվում են կորուտինների գործարկման համար:
    • launch: Գործարկում է նոր կորուտին և վերադարձնում Job (չի բլոկավորում):
      GlobalScope.launch {
          println("Կորուտին սկսվեց")
      }
      
    • async: Գործարկում է նոր կորուտին և վերադարձնում Deferred<T> (բլոկավորում .await()-ի ժամանակ):
      val deferred = GlobalScope.async {
          fetchData()
      }
      // ...
      val result = deferred.await() // Ապահովում արդյունքը
      
    • runBlocking: Բլոկավորում է ընթացիկ հոսքը մինչև կորուտինի ավարտը (օգտագործվում է հիմնականում բլոկավոր և ոչ բլոկավոր կոդերի միջև կամ թեստերում):
      runBlocking {
          val data = fetchData()
          println(data)
      }
      
  • CoroutineContext: տարրերի հավաքածու, որը որոշում է կորուտինի վարքագիծը, ներառյալ Dispatcher և Job:
    • Dispatcher: որոշում է հոսքը կամ հոսքերի խումբը, որտեղ կատարվում է կորուտինը:
  • Dispatchers: ներքին օբյեկտներ հոսքերի կառավարում համար:
    • Dispatchers.Default: ընդհանուր ֆոնային հոսքերի խումբ:
    • Dispatchers.IO: օպտիմալացված մուտք/ելք գործողությունների համար (դիսկային, ցանցային):
    • Dispatchers.Main: գլխավոր UI հոսքը (Android, JavaFX և այլն):
    • Dispatchers.Unconfined: սկսում է կորուտինին ընթացիկ հոսքում, բայց հետո կարող է շարունակվել ցանկացած հոսքում:
      GlobalScope.launch(Dispatchers.IO) {
          // կատարվում է մուտք/ելք հոսքում
      }
      
  • Կառուցված համաժամանակեցում: սկզբունք, ըստ որի կորուտինները ունեն ծնող (CoroutineScope) և ավտոմատ կերպով չեղարկվում են ծնողի չեղարկումից հետո: Սա կանխում է ռեսուրսների արտահոսքը և հեշտացնում է կյանքի ցիկլի կառավարումը:
    // CoroutineScope ավտոմատ կերպով կառավարում է դուստր կորուտինները
    val scope = CoroutineScope(Dispatchers.Default)
    val job = scope.launch {
        // ...
    }
    // Երբ scope-ը չեղարկվի, բոլոր դուստր կորուտինները չեղարկվում են
    scope.cancel()
    
  • Ցանցեր: Ցանցեր անվտանգ տվյալների փոխանցման համար կորուտինների միջև:
    • Unbuffered: Հաղորդումը կատարվում է միայն ուղարկումից հետո:
    • Buffered: թույլ է տալիս ուղարկել մի քանի տարր մինչև բլոկավորումը:
    • Conflated: պահում է միայն վերջին ուղարկված տարրը:
      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: Տվյալների հոսք, որը կարող է արտանետել մի քանի արժեքներ ասինխրոն: Դրա նման է RxJava Observable, բայց ավելի թեթև և ինտեգրված է կորուտինների հետ:
    fun simpleFlow(): Flow<Int> = flow {
        for (i in 1..3) {
            delay(100)
            emit(i) // Արժեքի արտանետում
        }
    }
    
    runBlocking {
        simpleFlow().collect { value -> println(value) } // Արտած արժեքների սպառում
    }
    

Այս հնարավորությունները թույլ են տալիս գրել ասինխրոն կոդը իպերատիվ ոճով, ինչը ավելի ընթեռնելի և պահպանելի է դարձնում, համեմատած callback-ների կամ Future-ների օգտագործման հետ։