Sobes.tech
Senior

Async ve await mekanizmaları nasıl çalışır?

sobes.tech yapay zeka

AI'dan gelen yanıt

Swift'te Async/await, yapılandırılmış eşzamanlılığa dayanır ve Dispatch/Global Actors kullanır. Arka planda çalışan mekanizmalar şunlardır:

  1. Continuation Stili: Asenkron fonksiyonlar, devamlar stiliyle derlenir. Anında bir değer döndürmek yerine, kontrol Swift çalışma zamanına aktarılır ve fonksiyonun mevcut durumu (yerel değişkenler, yürütme göstergesi) saklanır. Asenkron işlem tamamlandığında, çalışma zamanı fonksiyonun yürütmesini kaydedilen durumdan devam ettirir.

  2. Görev: Her async fonksiyon çağrısı, yapılandırılmış bir Task oluşturur veya ona katılır. Task, bir çalışma birimini temsil eder ve bir hiyerarşi oluşturur. Ana Task, alt Task'ların tamamlanmasını bekler.

  3. İş: Task, daha küçük iş birimlerine, yani Job'lara bölünür. Bir Job, bir yürütücüde çalıştırılabilecek bir kod parçasını temsil eder.

  4. Yürütücü: Yürütücü, Job'u başlatmaktan sorumludur. Standart kütüphane, çoğu asenkron görev için küresel DispatchQueue'ları yürütücü olarak kullanır. Belirli bağlamlar (örneğin, MainActor) kendi özel yürütücüleriyle gelir.

  5. Askıya Alma Noktaları: await, askıya alma noktasıdır. Bu noktaya gelindiğinde, fonksiyon askıya alınır, kontrol çağıran kod veya yürütücüye aktarılır ve mevcut Job sona erer. Swift çalışma zamanı fonksiyonun durumunu saklar.

  6. Devam: await ile beklenen asenkron işlem tamamlandığında, Swift çalışma zamanı yeni bir Job oluşturur ve askıya alınmış fonksiyonun yürütmesine devam eder. Bu Job, yürütücü kuyruğuna konur.

  7. İptal: Yapılandırılmış eşzamanlılık, hiyerarşik iptali destekler. Bir ana Task'ın iptali, otomatik olarak tüm alt Task'larını iptal eder. Asenkron işlemler, iptal durumunu kontrol edebilir ve uygun şekilde tepki verebilir.

İşte, bir async fonksiyonun derlenmesine ilişkin basitleştirilmiş bir örnek:

// Orijinal async fonksiyon
func fetchData() async -> Data {
    // Asenkron işlem
    let data = await URLSession.shared.data(from: url).0
    return data
}

// Derlemenin basitleştirilmiş temsili
// Döndürmek yerine, fonksiyon bir Continuation alır
func fetchData(_ continuation: Continuation<Data, Error>) {
    // Fonksiyonun başlangıç kodu
    let url = URL(string: "...")! // Örnek
    
    // Asenkron işlemi başlat
    URLSession.shared.data(from: url) { data, _, error in
        // Bu kapanış, asenkron işlemin tamamlanmasından sonra çalışır
        if let data = data {
            // Sonucu continuation'a ilet, fonksiyonu yeniden başlat
            continuation.resume(returning: data)
        } else if let error = error {
            continuation.resume(throwing: error)
        } else {
            // Diğer durumların işlenmesi
            continuation.resume(throwing: NSError(domain: "", code: 0, userInfo: nil))
        }
    }
    // Fonksiyon burada sona erer, resume çağrısını bekler
}

Await, temelde, Continuation yönetimi ve Job planlaması üzerinde sözdizimi şekeridir. Askıya alma, doğrudan akışı engellemez, bunun yerine yürütücüye diğer Job'ları yürütmesine izin verir.