ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift 5.5 - async & await
    Concurrency 2021. 9. 25. 11:33

    안녕하세요. 그린입니다🟢

    이번 포스팅에서는 Swift 5.5에서 새롭게 나온 async & await에 대해 학습해보겠습니다🧑🏻‍💻

     

    사실 나온지는 Swift 5.5가 나온 3월? 정도지만 이번에 Xcode13으로 업데이트하면서 같이 학습해보게 되었습니다😁

    async와 await가 이번 Swift 5.5에서 인기라고 하는데 왜 그런지 알아보겠습니다!

     

    async & await가 간략히 뭘해주나요?

    다른 유형의 비동기 처리 작업을 해주는 코드로 비동기 처리 코드를 동기 처리처럼 보일 수 있도록 지원

     

    이전 비동기 처리의 문제

    1. 비동기 처리 시 클로저 및 콜백을 통해 비동기 프로그래밍을 하다 보니 복잡도 증가

    2. 하나의 비동기 처리 일때는 크게 문제 없지만 여러 비동기 처리와 오류 처리가 섞이면서 많은 중첩이 발생

    func processImageData1(completionBlock: (_ result: Image) -> Void) {
        loadWebResource("dataprofile.txt") { dataResource in
            loadWebResource("imagedata.dat") { imageResource in
                decodeImage(dataResource, imageResource) { imageTmp in
                    dewarpAndCleanupImage(imageTmp) { imageResult in
                        completionBlock(imageResult)
                    }
                }
            }
        }
    }
    
    processImageData1 { image in
        display(image)
    }

    3. 위 문제점들로 인해 잦은 실수를 유발

    func processImageData4a(completionBlock: (_ result: Image?, _ error: Error?) -> Void) {
        loadWebResource("dataprofile.txt") { dataResource, error in
            guard let dataResource = dataResource else {
                return // <- forgot to call the block
            }
            loadWebResource("imagedata.dat") { imageResource, error in
                guard let imageResource = imageResource else {
                    return // <- forgot to call the block
                }
                ...
            }
        }
    }

     

    async & await를 사용하여 해결해보자면

    1. 동기 코드 형식의 폼을 보존하며 비동기 처리가 가능 (성능 향상)

    2. 코드를 디버깅, 프로파일링 및 탐색하는 동안 보다 일관된 경험을 제공하기 위한 더 나은 도구 (번역이 이렇지만 와닿지가 않음)

    3. 작업 우선 순위 및 취소와 같은 미래 동시성 기능을 위한 기반

    func loadWebResource(_ path: String) async throws -> Resource
    func decodeImage(_ r1: Resource, _ r2: Resource) async throws -> Image
    func dewarpAndCleanupImage(_ i : Image) async throws -> Image
    
    func processImageData() async throws -> Image {
      let dataResource  = try await loadWebResource("dataprofile.txt")
      let imageResource = try await loadWebResource("imagedata.dat")
      let imageTmp      = try await decodeImage(dataResource, imageResource)
      let imageResult   = try await dewarpAndCleanupImage(imageTmp)
      return imageResult
    }

    비동기 처리가 동기 함수 호출처럼 되게 간단해졌죠?!

     

    async & await 사용

    1. async

    비동기 작업을 정의하는 키워드로 해당 키워드가 붙으면 비동기적으로 동작한다는걸 알 수 있음

    func fetchImages() async throws -> [UIImage] {
        // .. perform data request
    }

    throws는 async의 위치 표현을 위한것으로 없어도 됨

    2. await

    비동기 함수 작업의 실행을 동기 시키는 오퍼랜드로 현재 작업 흐름에서 await를 만나면 해당 함수 처리가 끝날때까지 대기시킴

    func fetchData() async {
        do {
            try await fetchImages()
        } catch {
            // .. handle error
        }
    }

    await는 작업의 블락을 만들기에 async 키워드가 붙은 함수에서만 사용가능

     

    동기 속 비동기 처리

    동기 함수속에서 비동기 함수 처리를 해야할 경우 아래와 같이 Task 함수 클로저와 await를 통해 구현해줄 수 있다.

    func fetchData() {
        ...
        Task {
            do {
                try? await fetchImages()
            }
            catch {
                // .. Handle error
            }
        }
    }

    Task 함수 자체가 async로 마크되었기에 가능

     

    요약

    이렇게 간단하게? 음.. 전달하고자 하는 바는 간단하지 않겠지만 복잡하게 들어가면 한도 끝도 없을것 같아 간단하게 이해해버렸다..😱
    기존에 너무 복잡하게 쓰던 비동기 처리 작업을 바꿔놨지만 내부적으로는 복잡하게 처리되있겠지!? 그렇지만 표면적으로 보고 쓰기엔
    확실히 동기 코드처럼 접근하고 이해할 수 있으니 한결 비동기 처리가 편해졌다고 생각한다.
    아직 실무 코드에서 적용을 못했는데 앞으로 나올 비동기 처리에 대해 요런식으로 활용한다면 코드 복잡성과 가독성을 높아질것 같다👍🏻

     

    [참고자료]

    https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md

     

    GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Lang

    This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhance...

    github.com

    https://www.avanderlee.com/swift/async-await/

     

    Async await in Swift explained with code examples

    Async await in Swift allows to write asynchronous tasks with structured concurrency. Maintain readability in complex code.

    www.avanderlee.com

     

    'Concurrency' 카테고리의 다른 글

    Swift Concurrency - Parallel  (4) 2023.03.06
    Swift Concurrency - Task (4)  (8) 2023.03.02
    Swift Concurrency - Task (3)  (4) 2023.03.02
    Swift Concurrency - Task (2)  (2) 2023.02.27
    Swift Concurrency - Task (1)  (6) 2023.02.24
Designed by Tistory.