Sobes.tech
Senior

Механизмҳои async ва await дар зери капот чӣ гуна кор мекунанд?

sobes.tech AI

Ҷавоб аз AI

Async/await дар Swift асосан ба асоси ҳамоҳангсозии сохторӣ сохта шудааст ва истифодаи Dispatch/Global Actors-ро дорад. Механизмҳое, ки дар пасзамина кор мекунанд, инҳоянд:

  1. Style Continuation: Функсияҳои асинхронӣ ба услуби идомакунӣ компилют мешаванд. Ба ҷои баргардонидани фаврии арзиш, идоракунӣ ба runtime Swift мегузарад, ки ҳолати ҳозираи функсия (пайвандҳои маҳаллӣ, нишондиҳандаи иҷроиш)ро нигоҳ медорад. Вақте ки амалиёти асинхронӣ ба анҷом мерасад, runtime иҷроишро аз ҳолати нигоҳдошташуда такмил медиҳад.

  2. Task: Ҳар даъвати async функсия созиш ё пайваст мешавад ба Task сохторӣ. Task як воҳиди корро намояндагӣ мекунад ва hierarchical-ро месозад. Task падар интизор аст, ки Task-ҳои кӯдакиро ба анҷом расонад.

  3. Job: Task ба воҳидҳои хурдтарини кор, ки Job ном доранд, тақсим мешавад. Job як қисмати коди аст, ки метавонад дар иҷрокунанда (Executor) иҷро шавад.

  4. Executor: Иҷрокунанда масъул аст барои оғоз кардани Job. Дар китобхонаи стандартӣ, DispatchQueue-и глобалӣ ҳамчун иҷрокунанда барои зиёда аз корҳои асинхронӣ истифода мешаванд. Мавқеъҳои махсус (масалан, MainActor) иҷрокунандаҳои махсус доранд.

  5. Points of Suspension: await нуқтаи боздошт аст (suspension point). Вақте ки ба await мерасад, функсия боздошта мешавад, идоракунӣ ба коди даъваткунанда ё иҷрокунанда мегузарад ва Job-и ҳозира ба анҷом мерасад. Runtime Swift ҳолати функсияро нигоҳ медорад.

  6. Resumption: Вақте ки амалиёти асинхронӣ, ки ба он await интизор буд, ба анҷом мерасад, runtime Swift Job нав месозад барои идомаи иҷрои функсияи боздоштшуда. Ин Job ба навбат дар иҷрокунанда гузошта мешавад.

  7. Cancellation: Ҳамоҳангсозии сохторӣ дастгирӣ мекунад, ки hierarchical-ро бекор мекунад. Бекор кардани 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 аз continuation даъват шавад
}

Await дар асоси як сахтӣ аст, ки назорати Continuation ва нақшаи Job-ро дар иҷрокунанда таъмин мекунад. Боздоштан мустақиман наметавонад ҷараёнро банд кунад, балки иҷозат медиҳад, ки иҷрокунанда дигар Job-ҳоро иҷро кунад.