Kaip veikia async ir await mechanizmai po gaubtu?
sobes.tech AI
Atsakymas iš AI
Swift-те Async/await struktūruota konkurencija yra pagrįsta ir naudoja Dispatch/Global Actors. Mechanizmai, kurie veikia užkulisiuose, yra:
-
Tęsinio stilius: Asinchroninės funkcijos kompiliuojamos į tęsinio stilių. Vietoj tiesioginio grąžinimo reikšmės, valdymas perduodamas Swift runtime, kuris išsaugo funkcijos dabartinę būseną (vietines kintamąsias, vykdymo rodyklę). Kai asinchroninė operacija baigiasi, runtime atnaujina funkcijos vykdymą iš išsaugotos būsenos.
-
Task: Kiekvienas
asyncfunkcijos kvietimas sukuria arba prisijungia prie struktūruotoTask.Taskatstovauja darbo vienetą ir sukuria hierarchiją. TėvinisTasklaukia vaikųTaskužbaigimo. -
Job:
Taskyra suskaidomas į mažesnius darbo vienetus, vadinamusJob.Jobatstovauja kodo fragmentą, kuris gali būti vykdomas vykdytoju (Executor). -
Executor: Vykdytojas yra atsakingas už
Jobpaleidimą. Standartinėje bibliotekoje naudojami globalūsDispatchQueuekaip vykdytojai daugumai asinchroninių užduočių. Specializuoti kontekstai (pvz.,MainActor) turi savo specializuotus vykdytojus. -
Sustabdymo taškai:
awaityra sustabdymo taškas. Pasiekusawait, funkcija sustoja, valdymas perduodamas kviečiančiam kodui arba vykdytojui, o dabartinisJobužbaigiasi. Swift runtime išsaugo funkcijos būseną. -
Atnaujinimas: Kai asinchroninė operacija, kurios laukė
await, baigiasi, Swift runtime sukuria naująJobtęsti sustabdytos funkcijos vykdymą. ŠisJobįtraukiamas į vykdytojo eilę. -
Atšaukimas: Struktūruota konkurencija palaiko hierarchinį atšaukimą. Tėvinis
Taskatšaukimas automatiškai atšaukia visus jo vaikoTask. Asinchroninės operacijos gali tikrinti atšaukimo būseną ir atitinkamai reaguoti.
Štai supaprastintas async funkcijos kompiliacijos pavyzdys:
// Pradinė async funkcija
func fetchData() async -> Data {
// Asinchroninė operacija
let data = await URLSession.shared.data(from: url).0
return data
}
// Supaprastintas kompiliacijos vaizdas
// Vietoj grąžinimo, funkcija priima Continuation
func fetchData(_ continuation: Continuation<Data, Error>) {
// Funkcijos pradinis kodas
let url = URL(string: "...")! // Pavyzdys
// Asinchroninės operacijos paleidimas
URLSession.shared.data(from: url) { data, _, error in
// Šis blokas vykdomas po asinchroninės operacijos pabaigos
if let data = data {
// Rezultato perdavimas į continuation, funkcijos atnaujinimas
continuation.resume(returning: data)
} else if let error = error {
continuation.resume(throwing: error)
} else {
// Kitų atvejų apdorojimas
continuation.resume(throwing: NSError(domain: "", code: 0, userInfo: nil))
}
}
// Funkcija baigiasi čia, laukia resume iškvietimo iš continuation
}
Await iš esmės yra sintaksinis cukrus, kuris yra virš Continuation valdymo ir Job planavimo vykdytojui. Sustojimas tiesiogiai neužblokuoja srauto, bet leidžia vykdytojui vykdyti kitus Job-us.