비동기:
병렬: 동시에 여러부분이 실행됨
비동기함수
throws전에 async 키워드 작성func listPhotos(inGallery name: String) async -> [String] {
let result = // ... some asynchronous networking code ...
return result
}
await으로 표시await을 만나면 현재 쓰레드에서 코드의 실행을 일시 중단하고 대신 해당 쓰레드에서 다른 코드를 실행하기 때문에 이것을 쓰레드 양보 (yielding the thread) 라고함@main 으로 표시된 구조체, 클래스, 또는 열거형의 정적 (static) main() 메서드에 있는 코드Task.yeilde() : 명시적으로 중단 지점 추가Task.sleep(for:tolerance:clock:): 주어진 시간만큼 현재 작업 중단func listPhotos(inGallery name: String) async throws -> [String] {
try await Task.sleep(for: .seconds(2))
return ["IMG001", "IMG99", "IMG0404"]
}비동기 함수와 던지는 함수의 비교
async/await, throws/try)Result 타입이나 do-catch 블록을 이용해 동기 코드에서도 호출 가능await로 호출해야 하며, 동기 코드에서는 호출 불가능(구현시 하면 race condition, 데드락 등 문제 발생)throws는 동기 코드에서도 유연하게 처리 가능 (Result, do-catch)async는 무조건 비동기 흐름 안에서만 실행 가능for-await-in 루프는 다음 요소를 사용할 수 있을 때까지 기다리고 각 반복이 시작될 때 잠재적으로 실행을 일시 중단함import Foundation
let handle = FileHandle.standardInput
for try await line in handle.bytes.lines {
print(line)
}let 앞에 async 를 작성하고 상수를 사용할 때마다 await 를 작성함async let firstPhoto = downloadPhoto(named: photoNames[0])
async let secondPhoto = downloadPhoto(named: photoNames[1])
async let thirdPhoto = downloadPhoto(named: photoNames[2])
let photos = await [firstPhoto, secondPhoto, thirdPhoto]
show(photos)async let
TaskGroup
취소의 응답방식
CancellationError를 던짐 (에러 전파)nil이나 빈 배열 반환 (부분적인 결과)취소여부 확인 방법
checkCancellation()은 취소 시 에러로 처리 (간단)isCancelled은 조건문으로 유연하게 대응 가능 (예: 정리, 로그, 반환값 조절 등)취소 핸들러 사용(즉시반응 필요시)
Task.withTaskCancellationHandler(operation:onCancel:isolation:)메서드를 사용let task = await Task.withTaskCancellationHandler {
// ...
} onCancel: {
print("Canceled!")
}
// ... some time later...
task.cancel() // Prints "Canceled!"
Task {}를 사용해 현재 컨텍스트에서 독립적으로 작업 생성Task.detached {}는 현재 actor나 context와 완전히 분리된 작업 생성await 필요이유: 액터는 격리된 상태를 가지며, 외부 접근 시에는 비동기 중단점을 통해 조정해야 함
let logger = TemperatureLogger(label: "Outdoors", measurement: 25)
print(await logger.max) // ✅ OK
print(logger.max) // ❌ 컴파일 에러
await 없이도 안전하게 실행필요성