본문 바로가기

Swift

async/await란?

 

  • async: 비동기 작업을 수행할 수 있는 함수나 메서드를 선언할 때 사용합니다.
  • await: 비동기 작업의 결과를 기다릴 때 사용합니다.

 

기존에는 Swift에서 비동기 작업을 completion handler로 처리했기 때문에 코드가 복잡해지고 가독성이 떨어졌습니다.

// 기존의 Completion Handler 방식
func fetchData(completion: @escaping (String) -> Void) {
    DispatchQueue.global().async {
        completion("데이터 가져오기 완료")
    }
}

fetchData { result in
    print(result) // "데이터 가져오기 완료"
}

 

 

이 방식은 중첩된 클로저가 많아지면 코드가 복잡해지고, 에러 처리도 어려워집니다.

async/await는 이를 간단하고 직관적으로 바꿔줍니다!

 

async 함수 정의

  • 비동기 작업을 수행하려면 함수 선언부에 async 키워드를 추가합니다.
  • async 함수는 비동기 작업이 포함된 함수임을 나타냅니다. 
func fetchData() async -> String {
    return "데이터 가져오기 완료"
}

 

await로 비동기 작업 실행

  • async 함수의 결과를 기다릴 때는 await 키워드를 사용합니다.
  • await은 작업이 완료될 때까지 일시적으로 중단(suspend)되며, 완료되면 결과를 반환받습니다.

 

예제 1: 네트워크 요청

import Foundation

// 비동기 네트워크 요청 함수
func fetchWeather() async -> String {
    // 2초 동안 기다리는 작업 (예: 네트워크 요청)
    try? await Task.sleep(nanoseconds: 2_000_000_000)
    return "오늘의 날씨는 맑음"
}

// 비동기 함수 호출
func printWeather() async {
    let weather = await fetchWeather()
    print(weather)
}

// 프로그램 실행
Task {
    await printWeather()
}
2초 뒤에 "오늘의 날씨는 맑음" 출력

 

 

예제 2: 여러 비동기 작업 실행

import Foundation

// 비동기 작업 1
func task1() async -> String {
    try? await Task.sleep(nanoseconds: 1_000_000_000) // 1초 대기
    return "Task 1 완료"
}

// 비동기 작업 2
func task2() async -> String {
    try? await Task.sleep(nanoseconds: 1_000_000_000) // 1초 대기
    return "Task 2 완료"
}

// 비동기 작업 호출
func performTasks() async {
    let result1 = await task1()
    print(result1) // "Task 1 완료"

    let result2 = await task2()
    print(result2) // "Task 2 완료"
}

// 실행
Task {
    await performTasks()
}
1초 뒤에 "Task 1 완료" 출력
1초 뒤에 "Task 2 완료" 출력

 

예제 3: 에러 처리

enum NetworkError: Error {
    case invalidURL
}

// 비동기 네트워크 요청 함수
func fetchData(from url: String) async throws -> String {
    guard url == "https://example.com" else {
        throw NetworkError.invalidURL
    }
    try? await Task.sleep(nanoseconds: 1_000_000_000)
    return "데이터 가져오기 성공"
}

// 비동기 함수 호출 및 에러 처리
func performFetch() async {
    do {
        let data = try await fetchData(from: "https://example.com")
        print(data) // "데이터 가져오기 성공"
    } catch {
        print("에러 발생: \(error)")
    }
}

// 실행
Task {
    await performFetch()
}
1초 뒤에 "데이터 가져오기 성공" 출력