비동기 함수를 실행하는 함수를 표시하려면 '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 groups을 사용하여 동시성 코드를 구조화한다.
let userIDs = await withTaskGroup(of: Int.self) { taskGroup in
for server in ["primary", "secondary", "development"] {
taskGroup.addTask {
return await fetchUserID(from: server)
}
}
var results: [Int] = []
for await result in taskGroup {
results.append(result)
}
return results
}
Actors는 클래스와 유사하지만, 동일한 액터의 인스턴스에서 동시에 다른 비동기 함수가 안전하게 상호작용할 수 있도록 보장해준다.
actor ServerConnection {
var server: String = "primary"
private var activeUsers: [Int] = []
func connect() async -> Int {
let userID = await fetchUserID(from: server)
// ... communicate with server ...
activeUsers.append(userID)
return userID
}
}
Actor의 메서드를 호출하거나 해당 속성에 액세스할 때, 이미 실행 중인 다른 코드를 기다려야 할 수 있음을 나타내기 위해 해당 코드를 'await'로 표시한다.
let server = ServerConnection()
let userID = await server.connect()