completion handler VS async/awaitSwift 프로그래밍2022. 7. 7. 12:57
Table of Contents
completion handler VS async/await
개념이 뚜렷하게 잡히지 않아 혼자 여러 블로그를 참고하면서 공부함 (다시 공부하고 수정할 예정 !)
→ 냔지님 , 야곰님 등 참고
completion handler
definition 🌟
: The block to execute when the query completes.
쿼리가 완료됐을 때 실행하는 블록
Declaration ✔️
var completionHandler: ((Error?) -> Void)? { get set }
how to use it ❓
간단한 코드로 예를 들어보겠다.
func printHello(name : String, completionHandler : (String?) -> Void) {
let mes = "Hello ~\\(name)"
completionHandler(mes)
}
printHello(name : "가은"){ mes in
print(mes)
}
▶️ 구현할때 원하는 곳에 completionHandler를 호출하고, 함수를 call한 후 함수 실행이 완료됐으면 completionHandler에 전달해준 인자값으로 completionHandler를 실행 시켜준다.
async / await
definition 🌟
: 비동기 함수를 동기함수처럼 실행시켜 준다.
async : 비동기 함수임을 명시
await : 비동기 함수 호출 시, 함수 실행이 완료될 때까지 스레드를 대기시킨다.
Declaration ✔️
how to use it ❓
swift evolution에 나와있는 예제를 사용
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 로 비동기함수임을 명시하고, 호출할 때,비동기함수를 동기로 실행시킴.
- async awiat로 리팩토링
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)
}
⏬
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
}
- completion handler → async await로 바꿔보기 !
override func viewDidLoad() {
super.viewDidLoad()
self.getData { data in
self.decode(data: data) { contents in
print(contents) // "~~~~
}
}
}
func getData(completion: (Data) -> Void) {
let url = URL(string: "<https://zeddios.tistory.com>")!
let data = try! Data(contentsOf: url)
completion(data)
}
func decode(data: Data, completion: (String) -> Void) {
let contents = String(data: data, encoding: .utf8)!
completion(contents)
}
출처: <https://zeddios.tistory.com/1230> [ZeddiOS:티스토리]
- completion을 return으로 변경한다.
- func getData() -> Data { let url = URL(string: "<https://zeddios.tistory.com>")! let data = try! Data(contentsOf: url) return data } func decode(data: Data) -> String { let contents = String(data: data, encoding: .utf8)! return contents }
- async로 변경 !
- func getData() ✅ async ✅ -> Data { let url = URL(string: "<https://zeddios.tistory.com>")! let data = try! Data(contentsOf: url) return data } func decode(data: Data) ✅ async ✅ -> String { let contents = String(data: data, encoding: .utf8)! return contents }
- await로 호출
- 만약 비동기 함수가 에러를 던지면 try를 추가해야 함
- func process() async { do { let data = ✅ try ✅ await self.getData() let contents = ✅ try ✅ await self.decode(data: data) print(contents) } catch { } }
- func process() async { let data = ✅ await ✅ self.getData() let contents = ✅ await ✅ self.decode(data: data) print(contents) }
- 왜 completion handler 대신 async를 사용하려는 걸까?
- 코드가 복잡
- 에러가 발생했을 때 completion handler 호출이 return 시키기 때문에 종료 시점을 모름
- completionHandler 호출하는거 잊을 수도 있고
- 오류 처리를 어렵고 장황하게 만들고
- 비동기 호출간의 제어 흐름이 복잡할 때도 문제가 되고
- 심지어 매개변수 구문 @escaping (String) -> Void은 읽기 어려움!
'Swift 프로그래밍' 카테고리의 다른 글
[Swift Programming] 인스턴스 생성 및 소멸 (0) | 2022.07.26 |
---|---|
[Swift Programming] 프로퍼티와 메서드 (0) | 2022.07.12 |
[Swift Programming]구조체와 클래스 (0) | 2022.07.08 |
[Swift Programming] 옵셔널 (0) | 2022.07.07 |
@gani+ :: Gani_Dev :)
꾸준히 기록할 수 있는 사람이 되자 !