async: nedir, Deferred ve paralel coroutine nasıl çalışır

Yazar: IT Sectr Yayınlanma: 2026-06-22 Okuma süresi: 8 dk

async — Kotlin'de bir Coroutine Builder'dır, bir coroutine başlatır ve asenkron bir işlemin sonucunu almak için Deferred<T> nesnesi döndürür. async, birden çok görevi paralel olarak yürütmeye ve sonuçlarını await() aracılığıyla birleştirmeye olanak tanır. JetBrains rehberine göre, 2024, async, coroutine'lerde paralel hesaplamaları düzenlemenin tercih edilen yoludur.

Ana Noktalar

  • async — asenkron bir işlemin sonucunu içeren Deferred<T> döndüren bir coroutine builder
  • Deferred — Job'u miras alan, sonucu almak için await() metoduyla asenkron bir vaat
  • async bağımsız görevleri paralel olarak yürütmeye izin verir, toplam süreyi azaltır
  • await() — engellemeden sonuç elde edilene kadar coroutine'i askıya alan bir suspend fonksiyonu
  • Yapılandırılmış eşzamanlılık async ile hata durumunda tüm paralel görevlerin iptalini garanti eder

Kotlin Coroutines'de async nedir?

async — bir sonuç döndüren bir coroutine oluşturan CoroutineScope uzantı fonksiyonudur. launch'tan farklı olarak, async Deferred<T> döndürür — gelecekteki bir değeri temsil eden bir nesne. async ile başlatılan bir coroutine, diğer coroutine'lerle eşzamanlı olarak çalışarak hesaplamaların paralelleştirilmesine olanak tanır.

async, asenkron bir işlemin sonucunun daha sonraki işlemler için gerekli olduğu durumlarda kullanılır: birden çok kaynaktan veri yükleme, koleksiyonların toplu işlenmesi, çeşitli API'lere paralel istekler. Deferred hemen oluşturulur ve sonuç, coroutine tamamlandıktan sonra kullanılabilir hale gelir.

kotlin
import kotlinx.coroutines.*

suspend fun String.delayedValue(): String {
    delay(1000L)
    return this
}

fun main() = runBlocking {
    val deferred: Deferred<String> = async { "Hello".delayedValue() }
    println(deferred.await())
}

async ve Deferred Sözdizimi

async'in imzası launch'a benzer: aynı CoroutineContext, CoroutineStart parametreleri ve bir suspend bloğu. Fark, dönüş türündedir — Job yerine Deferred<T>, burada T bloğun son ifadesi tarafından döndürülen sonuç türüdür.

kotlin
public fun <T> CoroutineScope.async(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> T
): Deferred<T>

Deferred<T> — Job'u miras alan ve await(), getCompleted(), getCompletionExceptionOrNull() metodlarını ekleyen bir arayüzdür. await() bir suspend fonksiyonudur ve yalnızca bir coroutine veya başka bir suspend fonksiyonu içinde çağrılabilir. getCompleted(), coroutine henüz tamamlanmadıysa bir istisna fırlatan engelleyici olmayan bir metottur.

async ile Paralel Görevler

async'in ana avantajı, görevleri paralel olarak yürütme yeteneğidir. Her işlemi sırayla beklemek yerine (toplam süre = sürelerin toplamı), async coroutine'leri aynı anda başlatarak toplam süreyi en uzun işlem süresine indirir.

Paralel Veri Yükleme

Tipik bir senaryo — üç paralel async isteğiyle kullanıcı profili, ayarları ve sipariş geçmişini yüklemek. Üçü de tamamlandıktan sonra sonuçlar tek bir veri modelinde birleştirilir.

kotlin
suspend fun loadUserDashboard(userId: String): Dashboard = coroutineScope {
    val profile = async { api.getProfile(userId) }
    val settings = async { api.getSettings(userId) }
    val orders = async { api.getRecentOrders(userId) }

    Dashboard(
        profile = profile.await(),
        settings = settings.await(),
        orders = orders.await()
    )
}

coroutineScope fonksiyonu alt coroutine'leri başlatır ve sonucu döndürmeden önce tamamlanmalarını bekler. Bloğun tamamı sıralı değil, paralel olarak yürütülür.

Deferred Sonuçlarını İşleme

Deferred, sonuçla çalışmak için birden çok metodu destekler. await()'e ek olarak, durumu kontrol etme, tamamlanmış değeri alma ve Kotlin Coroutines yardımcı fonksiyonları aracılığıyla birden çok Deferred'i birleştirme metodları vardır.

MetotAçıklamaSuspend?
await()Sonuç elde edilene kadar coroutine'i askıya alırEvet
getCompleted()Coroutine tamamlandıysa sonucu döndürür (yoksa Exception)Hayır
getCompletionExceptionOrNull()Hata durumunda istisnayı veya null döndürürHayır
isCompletedCoroutine'in tamamlanıp tamamlanmadığını kontrol ederHayır

Bir Deferred listesini birleştirmek için awaitAll() kullanılır — koleksiyondaki tüm Deferred'ler tamamlanana kadar yürütmeyi askıya alan bir fonksiyon. En az biri hatayla tamamlanırsa, awaitAll() istisnayı fırlatır.

kotlin
suspend fun <T> loadAll(requests: List<suspend () -> T>): List<T> {
    return coroutineScope {
        val deferreds = requests.map { async { it() } }
        deferreds.awaitAll()
    }
}

async ve launch Arasındaki Farklar

async ve launch arasındaki seçim, coroutine sonucunun gerekli olup olmadığına bağlıdır. launch Job döndürür ve fire-and-forget işlemleri için uygundur, async Deferred döndürür ve veri döndüren görevler için kullanılır. Sözdizimi ve parametreler açısından builder'lar aynıdır.

  • launch → Job (sonuç yok), async → Deferred<T> (sonuç T)
  • launch — fire-and-forget görevleri (kayıt, önbellekleme, analitik gönderme)
  • async — paralel hesaplamalar (birden çok API'den yükleme, toplu işleme)
  • Her ikisi de yapılandırılmış eşzamanlılık ve CoroutineStart parametrelerini destekler
  • await() yalnızca Deferred için kullanılabilir, launch sonuç sağlamaz

Önemli kural: fire-and-forget için asla async kullanmayın. Coroutine sonucu gerekli değilse, launch kullanın. async, Deferred oluşturma yükü getirir ve bu tür senaryolarda haklı gösterilemez.

Mobil Geliştirmede async Örnekleri

Android'de async, ViewModel ve UseCases içindeki paralel işlemler için kullanılır. Tipik senaryolar: profil ve haber akışını aynı anda yükleme, birden çok hava durumu servisinden hava durumu alma, sunucuyla toplu veri senkronizasyonu.

kotlin
class HomeViewModel : ViewModel() {
    fun loadHomeScreen() {
        viewModelScope.launch {
            val userData = async(Dispatchers.IO) { repository.getUserData() }
            val newsFeed = async(Dispatchers.IO) { repository.getNewsFeed() }
            val notifications = async(Dispatchers.IO) { repository.getNotifications() }

            val state = HomeState(
                user = userData.await(),
                news = newsFeed.await(),
                unread = notifications.await()
            )
            _uiState.update { state }
        }
    }
}

Hata yalıtımı için bir async grubunun coroutineScope veya supervisorScope ile sarılması önerilir. supervisorScope, biri başarısız olsa bile diğer async coroutine'lerin devam etmesine izin verir — kritik olmayan işlemler için kullanışlıdır.

Sıkça Sorulan Sorular

async await olmadan kullanılabilir mi?

Kullanılabilir, ancak anlamsızdır. await() olmadan async bir coroutine başlatır ancak sonucu kaybolur. Sonuç gerekli değilse, launch kullanın — Deferred oluşturmaz ve bellek ve performans açısından daha verimlidir.

async istisnaları nasıl işler?

async içindeki bir istisna Deferred'de saklanır. await() çağrısı bu istisnayı fırlatır. Fırlatmadan kontrol etmek için getCompletionExceptionOrNull() kullanın. coroutineScope kullanıldığında, bir hata tüm alt coroutine'leri iptal eder.

Kotlin Coroutines'de awaitAll nedir?

awaitAll() — Iterable<Deferred<T>> için bir uzantı fonksiyonudur, tüm Deferred'ler tamamlanana kadar coroutine'i askıya alır. Sonuçların bir listesini döndürür. En az bir Deferred başarısız olursa, istisnayı fırlatır ve kalanları iptal eder.

async, GlobalScope.async'ten nasıl farklıdır?

Evet. async, kapsama bağlı bir CoroutineScope uzantı fonksiyonudur. GlobalScope.async yaşam döngüsüne bağlı olmayan bir coroutine oluşturur — süresiz olarak çalışabilir. GlobalScope, sızıntı riski nedeniyle Android'de önerilmez.

Paralel istekler için kaç async coroutine başlatılabilir?

Sayı, dağıtıcı tarafından belirlenir: Dispatchers.IO en fazla 64 eşzamanlı iş parçacığını destekler, Dispatchers.Default — CPU çekirdeği sayısına kadar. Toplu işlemler için Semaphore veya awaitAll ile mapNotNull aracılığıyla sınırlı paralellik kullanın.

Özet

  • async — asenkron sonuç alma için Deferred<T> döndüren bir coroutine builder
  • Deferred Job'u miras alır ve await(), getCompleted(), getCompletionExceptionOrNull() metodlarını ekler
  • Paralel yürütme async ile toplam süreyi en uzun işlemin süresine indirir
  • awaitAll() — bir koleksiyondaki tüm Deferred'leri beklemek için bir yardımcı
  • coroutineScope — iptal garantisiyle bir async grubu için önerilen sarmalayıcı
  • async'i fire-and-forget için kullanmayın — bunun yerine launch kullanın
  • Android'de async, viewModelScope ile ViewModel'de paralel yükleme için kullanılır

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun