비동기적으로 실행되는 함수를 나타내기 위해 async를 사용한다.
func fetchUserID(from server: String) async -> Int {
if server == "primary" {
return 97
}
return 501
}
앞에 await를 작성하여 비동기 함수를 호출하는 것을 나타낸다.
func fetchUsername(from server: String) async -> String {
let userID = await fetchUserID(from: server)
if userID == 501 {
return "John Appleseed"
}
return "Guest"
}
비동기 함수를 호출하기 위해 async let을 사용하여 다른 비동기 코드와 병렬로 실행할 수 있다.
await를 작성하여 반환된 값을 사용한다.
func connectUser(to server: String) async {
async let userID = fetchUserID(from: server)
async let username = fetchUsername(from: server)
let greeting = await "Hello \(username), user ID \(userID)"
print(greeting)
}
비동기 함수의 반환을 기다리지 않고 동기 코드에서 비동기 함수를 호출하려면 Task를 사용한다.
Task {
await connectUser(to: "primary")
}
// Prints "Hello Guest, user ID 97"
동시성 코드를 구성하기 위해 작업 그룹(task group)을 사용한다.
let userIDs = await withTaskGroup(of: Int.self) { group in
for server in ["primary", "secondary", "development"] {
group.addTask {
return await fetchUserID(from: server)
}
}
var result: [Int] = []
for await result in group {
result.append(result)
}
return results
}
액터는 다양한 비동기 함수가 동시에 동일한 액터의 인스턴스와 안전하게 상호작용할 수 있다는 것을 제외하고는 클래스와 유사하다.
actor ServerConnection {
var server: String = "primary"
private var activeUsers: [Int] = []
func connect() async -> Int {
let userID = await fetchUserID(from: server)
activeUsers.append(userID)
return userID
}
}
액터의 메소드를 호출하거나 프로퍼티에 접근할 때,
액터에서 이미 실행 중인 다른 코드가 완료될 때까지 기다리고 있는 것을 나타내기 위해 코드에 await를 표기한다.
let server = ServerConnection()
let userID = await server.connect()