🔥 비동기 함수를 병렬로 호출하기

448자
6분

비동기 함수를 await로 호출하면 한 번에 하나의 코드 조각만 실행됩니다. 비동기 코드가 실행되는 동안 호출자는 해당 코드가 완료될 때까지 기다린 후 다음 코드 줄로 넘어가 실행하게 되죠. 예를 들어, 갤러리에서 처음 세 개의 사진을 가져오려면 다음과 같이 downloadPhoto(named:) 함수를 세 번 호출할 수 있습니다.

let firstPhoto = await downloadPhoto(named: photoNames[0])
let secondPhoto = await downloadPhoto(named: photoNames[1])
let thirdPhoto = await downloadPhoto(named: photoNames[2])
// 첫 번째, 두 번째, 세 번째 사진을 순차적으로 다운로드합니다.
 
let photos = [firstPhoto, secondPhoto, thirdPhoto]
// 다운로드한 사진들을 photos 배열에 저장합니다.
 
show(photos)
// photos 배열에 저장된 사진들을 보여줍니다.
swift

이 접근 방식에는 중요한 단점이 있습니다. 다운로드는 비동기적이어서 진행되는 동안 다른 작업이 가능하지만, 한 번에 downloadPhoto(named:) 호출이 하나씩만 실행됩니다. 각 사진은 다음 사진 다운로드가 시작되기 전에 완전히 다운로드됩니다. 하지만 이러한 작업을 기다릴 필요는 없습니다. 각 사진은 독립적으로, 심지어 동시에 다운로드할 수 있기 때문이죠.

비동기 함수를 호출하고 주변 코드와 병렬로 실행되도록 하려면 상수를 정의할 때 let 앞에 async를 작성하고 상수를 사용할 때마다 await를 작성하면 됩니다.

async let firstPhoto = downloadPhoto(named: photoNames[0])
async let secondPhoto = downloadPhoto(named: photoNames[1])
async let thirdPhoto = downloadPhoto(named: photoNames[2])
// 첫 번째, 두 번째, 세 번째 사진을 병렬로 다운로드합니다.
 
let photos = await [firstPhoto, secondPhoto, thirdPhoto]
// 모든 사진의 다운로드가 완료될 때까지 기다린 후, photos 배열에 저장합니다.
 
show(photos)
// photos 배열에 저장된 사진들을 보여줍니다.
 
swift

이 예제에서는 downloadPhoto(named:)에 대한 세 번의 호출이 이전 호출이 완료되기를 기다리지 않고 시작됩니다. 사용 가능한 시스템 리소스가 충분하다면 동시에 실행될 수 있습니다. 코드가 함수의 결과를 기다리기 위해 일시 중단되지 않기 때문에 이러한 함수 호출 중 어느 것도 await로 표시되지 않습니다. 대신 photos가 정의되는 줄까지 실행이 계속됩니다. 이 시점에서 프로그램은 이러한 비동기 호출의 결과가 필요하므로 await를 작성하여 세 개의 사진이 모두 다운로드될 때까지 실행을 일시 중지합니다.

이 두 가지 접근 방식의 차이점은 다음과 같이 생각해 볼 수 있습니다.

  • 다음 줄의 코드가 해당 함수의 결과에 의존하는 경우 await로 비동기 함수를 호출하세요. 이는 순차적으로 수행되는 작업을 생성합니다.
  • 코드의 나중에 결과가 필요할 때까지 async-let으로 비동기 함수를 호출하세요. 이는 병렬로 수행될 수 있는 작업을 생성합니다.
  • awaitasync-let 모두 일시 중단된 동안 다른 코드가 실행될 수 있도록 허용합니다.
  • 두 경우 모두 await로 가능한 일시 중단 지점을 표시하여 비동기 함수가 반환될 때까지 필요한 경우 실행이 일시 중지됨을 나타냅니다.

같은 코드에서 이 두 가지 접근 방식을 혼합해서 사용할 수도 있답니다. 상황에 맞게 적절한 방식을 선택하여 비동기 함수를 활용해 보세요. 병렬 처리를 통해 효율적인 코드를 작성할 수 있을 거예요!

병렬 처리의 장점을 한 눈에 보여주는 예시를 다이어그램으로 살펴볼까요?

lecture image

위 다이어그램에서 볼 수 있듯이, 순차 처리는 각 사진을 차례로 다운로드하는 데 총 9초가 걸리는 반면, 병렬 처리는 세 개의 사진을 동시에 다운로드하여 3초 만에 완료할 수 있습니다. 병렬 처리를 활용하면 작업 시간을 크게 단축할 수 있겠죠?

이처럼 Swift의 비동기 프로그래밍 기능을 활용하면 효율적이고 반응성이 뛰어난 애플리케이션을 개발할 수 있습니다.