Ինչպես են աշխատում async և await մեխանիզմները թաքնված?
sobes.tech AI
Պատասխան AI-ից
Swift- ի Async/await կառուցվածքային կոնկուրենության վրա է հիմնված և օգտագործում է Dispatch/Global Actors-ները: Մտածող մեխանիզմները, որոնք աշխատում են ներքևում, են՝
-
Կոնտինյուացիայի ոճը: Ասինխրոն ֆունկցիաները կոմպիլյացվում են կոնտինյուացիայի ոճով: Փոխարենը անմիջապես վերադարձնել արժեքը, կառավարումը փոխանցվում է Swift runtime-ին, որը պահպանում է ֆունկցիայի ընթացիկ վիճակը (տեղական փոփոխականներ, կատարողական ցուցիչ): Երբ ասինխրոն օպերացիան ավարտվի, runtime-ը վերականգնում է ֆունկցիայի կատարումը պահված վիճակից:
-
Task: Յուրաքանչյուր
asyncֆունկցիայի կանչը ստեղծում կամ միանում է կառուցվածքայինTask-ին:Taskներկայացնում է աշխատանքային միավոր և ձևավորում է հիերարխիա: ՊատկանողTask-ը սպասում է ենթաTask-ների ավարտին: -
Job:
Task-ը բաժանվում է փոքր աշխատանքային միավորների՝Job-ների:Job-ը ներկայացնում է կոդի հատված, որը կարող է կատարվել կատարողում (Executor): -
Executor: Կատարողը պատասխանատու է
Job-ի մեկնարկի համար: Ստանդարտ գրադարանում օգտագործվում են գլոբալDispatchQueue-ներ որպես կատարողներ մեծամասնության ասինխրոն առաջադրանքների համար: Սպեցիֆիկ կոնտեքստերը (օր.,MainActor) ունեն իրենց մասնագիտացված կատարողներ: -
Հետաձգման կետեր:
await-ը հապաղման կետ է: Երբ հասնում էawait-ին, ֆունկցիան դադարում է, կառավարումը փոխանցվում է կանչող կոդին կամ կատարողին, և ընթացիկJob-ը ավարտվում է: Swift runtime-ը պահպանում է ֆունկցիայի վիճակը: -
Վերականգնում: Երբ ասինխրոն օպերացիան, որի սպասում էր
await-ը, ավարտվի, Swift runtime-ը ստեղծում է նորJob՝ շարունակելու համար դադարեցված ֆունկցիայի կատարումը: ԱյսJob-ը դրվում է կատարողի հերթում: -
Չեղարկում: Կառուցվածքային կոնկուրենությունը աջակցում է հիերարխիկ չեղարկմանը: Պատկանող
Task-ի չեղարկումը ավտոմատ կերպով չեղարկում է նրա բոլոր ենթաTask-ները: Ասինխրոն օպերացիաները կարող են ստուգել չեղարկման կարգավիճակը և համապատասխան արձագանքել:
Ստորև ներկայացված է պարզեցված օրինակ async ֆունկցիայի կոմպիլյացիայի մասին՝
// Արժեքային async ֆունկցիա
func fetchData() async -> Data {
// Ասինխրոն օպերացիա
let data = await URLSession.shared.data(from: url).0
return data
}
// Պարզեցված ներկայացում կոմպիլյացիայի
// Փոխարենը վերադարձի, ֆունկցիան ընդունում է Continuation
func fetchData(_ continuation: Continuation<Data, Error>) {
// Ֆունկցիայի սկզբնական կոդը
let url = URL(string: "...")! // Օրինակ
// Աշխատանքի ասինխրոն մեկնարկ
URLSession.shared.data(from: url) { data, _, error in
// Այս փակումը կատարվում է հետո ասինխրոն օպերացիայի ավարտին
if let data = data {
// Տվյալների փոխանցում continuation-ին, ֆունկցիայի վերականգնում
continuation.resume(returning: data)
} else if let error = error {
continuation.resume(throwing: error)
} else {
// Այլ դեպքերի մշակումը
continuation.resume(throwing: NSError(domain: "", code: 0, userInfo: nil))
}
}
// Ֆունկցիան ավարտվում է այստեղ, սպասում է resume-ի կանչին
}
Await-ը հիմնականում սինտաքսիկ շաքար է Continuation-ի կառավարման և Job-ի պլանավորման վրա կատարողին: Հետաձգումը ուղղակիորեն չի բլոկավորում հոսքը, այլ թույլ է տալիս կատարողին իրականացնել այլ Job-եր։