티스토리 뷰
Asynchronous Sequences
이전 섹션의 listPhotos(inGallery:) 함수는 배열의 모든 요소가 준비된 후 전체 배열을 한 번에 비동기식으로 반환합니다.
또 다른 접근 방식은 비동기 시퀀스(asynchronous sequence)를 사용하여 한 번에 하나의 컬렉션 요소를 대기하는 것입니다.
다음은 비동기 시퀀스를 반복(iterating)하는 방법입니다.
import Foundation
let handle = FileHandle.standardInput
for try await line in handle.bytes.lines {
print(line)
}
위의 예는 일반적인 for-in 루프를 사용하는 대신 await 를for뒤에 씁니다.
비동기 함수 또는 메서드를 호출할 때와 마찬가지로 await는 가능한 일시 중단 지점을 나타냅니다.
대기 루프는 잠재적으로 다음 요소가 사용 가능하기를 기다리는 각 반복의 시작 부분에서 실행을 중단합니다.
Sequence 프로토콜을 추가하여 for-in 루프를 사용할 수 있는 것과 마찬가지로, AsyncSequence 프로토콜을 추가하여 for-await-in 루프를 사용할 수 있습니다.
Calling Asynchronous Functions in Parallel
비동기 함수를 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]
show(photos)
이 접근 방식에는 다음과 같은 중요한 단점이 있습니다.
다운로드가 비동기식이므로 다른 작업이 진행되는 동안에도 downloadPhoto(named:) 는 한 번에 하나만 실행됩니다.
각 사진은 다음 사진 다운로드가 시작되기 전에 완전히 다운로드됩니다.
그러나 각 사진을 개별적으로 다운로드하거나 동시에 다운로드할 수 있으므로 작업을 기다릴 필요가 없습니다.
비동기 함수를 호출하여 주변 코드와 병렬로 실행하려면 상수를 정의할 때 let 앞에 async를 씁니다.
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]
show(photos)
이 예에서는 이전 호출이 완료될 때까지 기다리지 않고 downloadPhoto(named:) 세 가지 호출이 모두 시작됩니다.
사용 가능한 시스템 리소스가 충분하면 리소스를 동시에 실행할 수 있습니다.
코드가 함수의 결과를 대기하기 위해 일시 중단되지 않기 때문에 이러한 함수 호출 중 어떤 것도 await로 표시되지 않습니다.
대신, photos가 정의된 라인까지 실행이 계속됩니다.
이 시점에서 프로그램은 이러한 비동기 호출의 결과를 필요로 하므로 세 개의 사진이 모두 다운로드될 때까지 실행을 일시 중지하기 위해 await를 작성합니다.
다음은 이러한 두 가지 접근 방식의 차이점을 생각해 볼 수 있는 방법입니다.
- 다음 줄의 코드가 해당 함수의 결과에 따라 달라지는 경우 await를 사용하여 비동기 함수를 호출합니다. 이것은 순차적으로 수행되는 작업을 만듭니다.
- 코드에서 나중까지 결과가 필요하지 않을 때 async-let 비동기 함수를 호출합니다. 이것은 병렬로 수행될 수 있는 작업을 만듭니다.
- await 와 async-let 모두 일시 중단된 동안 다른 코드를 실행할 수 있습니다.
- 두 경우 모두 가능한 일시 중단 지점을 await로 표시하여 필요한 경우 비동기 함수가 돌아올 때까지 실행이 일시 중지됨을 나타냅니다.
동일한 코드에서 이 두 가지 접근 방식을 혼합할 수도 있습니다.
다음글
[iOS] Concurrency(4) - Tasks and Task Groups
'Swift' 카테고리의 다른 글
[Swift] Concurrency(5) - Actors (0) | 2022.12.15 |
---|---|
[Swift] Concurrency(4) - Tasks and Task Groups (0) | 2022.12.15 |
[Swift] Concurrency(2) - 비동기함수 정의와 호출 (0) | 2022.12.14 |
[Swift] Concurrency(1) - Concurrency란 (0) | 2022.12.14 |
[Swift] Improving Build Efficiency with Good Coding Practices 번역 (0) | 2022.10.02 |