기존의 비동기 코드(콜백, 델리게이트 등등)을 async/await 패턴으로 변환할 때 사용하는 핵심 개념
비동기 함수의 실행 상태를 저장하고, 중단된 지점에서 재개 할 수 있도록 하는 객체
func fetchData(completion: @escaping (Result<String, Error>) -> Void) {
// 비동기 작업 수행 후 completion 호출
completion(.success("데이터"))
}
func fetchDataAsync() async throws -> String {
return try await withCheckedThrowingContinuation { continuation in
fetchData { result in
switch result {
case .success(let data):
continuation.resume(returning: data)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
기존의 콜백 기반 함수를 aync/await 스타일로 쉽게 변환 가능.
런타임에서
resume이 중복 호출되는지 확인 (런타임 에러) 및 async/await 스타일로 변환해주는 함수
// 기존 콜백 기반 함수
func loadData(completion: @escaping (Result<String, Error>) -> Void) {
// 비동기 작업
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
completion(.success("Loaded Data"))
}
}
// async/await로 변환
func loadDataAsync() async throws -> String {
try await withCheckedThrowingContinuation { continuation in
loadData { result in
switch result {
case .success(let data):
continuation.resume(returning: data)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
/*
func myFunction() async -> String {
return await withCheckedContinuation { continuation in
// 비동기 작업 수행
// 완료 시:
continuation.resume(returning: "결과값")
}
}
*/
}
withCheckedThrowingContinuation: Error 던짐
성공 시: resume(returning:)
실패 시: resume(throwing:)
withCheckedContinuation: Error 안 던짐
런타임에 resume의 중복, 누락 체크 O
런타임에 체크하므로, 약간의 오버헤드 발생
안정성 향상
런타임에서
resume이 중복 호출 확인X 및 async/await 스타일로 변환해주는 함수
func fetchData(url: URL) async -> Data? {
await withUnsafeContinuation { continuation in
URLSession.shared.dataTask(with: url) { data, _, _ in
continuation.resume(returning: data)
}.resume()
}
}
func loadAsync() async throws -> String {
try await withUnsafeThrowingContinuation { continuation in
someAsyncFunction { result, error in
if let result = result {
continuation.resume(returning: result)
} else if let error = error {
continuation.resume(throwing: error)
}
}
}
}
resume의 중복, 누락 체크 Xhttps://github.com/swiftlang/swift-evolution/blob/main/proposals/0300-continuation.md