Swift의 async 와 await
Swift 5.5 에서 도입된 async 와 await는 비동기 작업을 더욱 간단하고 직관적으로 작성할 수 있게 해주는 기능이다. 이를 통해 기존의 클로저와 콜백 기반 코드에서 발생하는 복잡성과 가독성 문제를 해결할수 있다.
async
async는 함수가 비동기 작업을 수행한다는 것을 나타내는 키워드이다. 비동기 함수는 동기적으로 실행되지 않으며, 호출 시 함수가 백그라운드에서 작업을 처리한다.
async 사용 예제코드
func fetchData() async -> String {
return "Data"
}
await
await는 비동기 작업의 결과가 완료될 때까지 기다리는 키워드이다. 이를 통해 비동기 작업의 결과를 순차적으로 처리할 수 있다.
await 사용 예제코드
Task {
let result = await fetchData()
print(result) // 출력 : Data
}
async 와 await의 동작 원리
async와 await는 협력적 중단(cooperative suspension) 메커니즘을 기반으로 한다. 이는 비동기 함수가 실행 중에 특정 지점에서 다른 작업에 제어를 넘기고, 필요한 시점에 다시 실행을 이어갈 수 있도록 설계되었다.
동작 과정
1. 비동기 작업 호출: async 함수는 호출되면 백그라운드에서 작업이 진행된다.
2. 작업 대기: await는 호출한 작업이 완료될 때까지 기다린다.
3. 작업 재개: 작업이 완료되면 await 이후의 코드가 실행된다.
예제코드
func fetchData() async throws -> String {
try await Task.sleep(nanoseconds: 1_000_000_000) // 1초 대기
return "Data fetched"
}
func processData() async {
do {
let data = try await fetchData()
print("Processed \(data)")
} catch {
print("error")
}
}
Task {
await processData()
}
async 와 await의 장점
1. 가독성 향상: 복잡한 콜백 체인을 동기 코드처럼 간결하게 작성할 수 있다.
2. 에러 처리 통합: try, await, do-catch를 사용해 비동기 작업에서도 에러를 일관되게 처리할 수 있다.
3. 병렬 처리 지원: 여러 비동기 작업을 병렬로 실행하며 결과를 기다릴 수 있다.
병렬 처리 예제코드
func fetchUser() async throws -> String {
try await Task.sleep(nanoseconds: 1_000_000_000)
return "User Data"
}
func fetchPosts() async throws -> String {
try await Task.sleep(nanoseconds: 2_000_000_000)
return "Posts Data"
}
Task {
do {
async let user = fetchUser()
async let posts = fetchPosts()
let result = try await(user, posts)
print(result)
} catch {
print("error")
}
}
async와 await의 주의 사항
1. 호출 제약: async 함수는 다른 async 함수 또는 Task 내부에서만 호출할 수 있다.
2. 메모리 관리: 비동기 작업이 중단된 상태에서도 메모리 리소스가 유지되므로, 작업 수가 많아질 경우 메모리 사용량을 주의해야 한다.
3. 에러 전파: 비동기 작업 중 발생한 에러는 반드시 적절히 처리해야 한다.
기존 콜백 코드와 비교
기존 콜백 코드
func fetchData(completion: @escaping (String) -> Void) {
DispatchQueue.global().async {
completion("Fetched Data")
}
}
fetchData { result in
print(result)
}
async/await 코드
func fetchData() async -> String {
return "Fetched Data"
}
Task {
let result = await fetchData()
print(result)
}
콜백 기반 코드는 중첩이 많아질수록 가독성이 떨어지는 것에 비해 async/await 을 사용한 코드는 더 간결하고 가독성이 좋은 코드로 작성할 수 있다는 것을 확인할 수 있다.
'TIL(Today I Learned)' 카테고리의 다른 글
| 2025.01.13 Today I Learned (0) | 2025.01.13 |
|---|---|
| 2025.01.07 Today I Learned (0) | 2025.01.07 |
| 2025.01.02 Today I Learned (0) | 2025.01.02 |
| 2025.01.01 Today I Learned (0) | 2025.01.01 |
| 2024.12.24 Today I Learned (0) | 2024.12.23 |