본문 바로가기
TIL(Today I Learned)

2025.01.06 Today I Learned

by 승환파크 2025. 1. 6.

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