Kako funkcionišu mehanizmi async i await ispod haube?
sobes.tech АИ
Одговор од АИ
Async/await u Swiftu zasnovan je na strukturiranoj konkurenciji i koristi Dispatch/Global Actors. Mehanizmi koji rade ispod haube su:
-
Stil nastavka: Asinhrone funkcije se kompajliraju u stil nastavka. Umesto da odmah vrate vrednost, kontrola se prenosi na Swift runtime, koji čuva trenutno stanje funkcije (lokalne promenljive, pokazivač izvršenja). Kada asinhrona operacija završi, runtime nastavlja izvršenje funkcije od sačuvanog stanja.
-
Task: Svaki poziv
asyncfunkcije kreira ili se pridružuje strukturiranojTask.Taskpredstavlja jedinicu rada i formira hijerarhiju. RoditeljskiTaskčeka završetak podređenihTask. -
Job:
Taskse razbija na manje jedinice rada, nazvaneJob.Jobpredstavlja fragment koda koji može biti izvršen na izvršiocu (Executor). -
Executor: Izvršilac je odgovoran za pokretanje
Job. U standardnoj biblioteci se koriste globalniDispatchQueuekao izvršioci za većinu asinhronih zadataka. Specijalizovani konteksti (npr.,MainActor) imaju svoje specijalizovane izvršioca. -
Tačke suspendovanja:
awaitje tačka suspendovanja (suspension point). Kada dosegneawait, funkcija se zaustavlja, kontrola se prenosi na pozivajući kod ili izvršioca, a trenutniJobse završava. Swift runtime čuva stanje funkcije. -
Resumption: Kada asinhrona operacija na koju je čekao
awaitzavrši, Swift runtime kreira noviJobza nastavak izvršavanja suspendovane funkcije. OvajJobse stavlja u red na izvršiocu. -
Otkazivanje: Strukturirana konkurencija podržava hijerarhijsko otkazivanje. Otkazivanje roditeljskog
Taskautomatski otkazuje sve njegove podređeneTask. Asinhrone operacije mogu proveravati status otkazivanja i reagovati u skladu s tim.
Evo pojednostavljenog primera kompilacije async funkcije:
// Početna async funkcija
func fetchData() async -> Data {
// Asinhrona operacija
let data = await URLSession.shared.data(from: url).0
return data
}
// Pojednostavljeni prikaz kompilacije
// Umesto povratka, funkcija prihvata Continuation
func fetchData(_ continuation: Continuation<Data, Error>) {
// Početni kod funkcije
let url = URL(string: "...")! // Primer
// Pokretanje asinhrone operacije
URLSession.shared.data(from: url) { data, _, error in
// Ovaj blok se izvršava nakon završetka asinhrone operacije
if let data = data {
// Prenos rezultata u continuation, nastavak funkcije
continuation.resume(returning: data)
} else if let error = error {
continuation.resume(throwing: error)
} else {
// Obrada drugih slučajeva
continuation.resume(throwing: NSError(domain: "", code: 0, userInfo: nil))
}
}
// Funkcija se završava ovde, čekajući poziv resume od continuation
}
Await je u suštini sintaktički šećer nad upravljanjem Continuation i planiranjem Job na izvršiocu. Zaustavljanje ne blokira direktno nit, već omogućava izvršiocu da izvršava druge Job-ove.