https://medium.com/@GetInRhythm/closures-vs-combine-vs-async-await-993eb1da4d44
스위프트에는 클로저, 컴바인, 어싱크/어웨잇 3가지의 비동기 코드 작성 방식이 존재함. 클로저는 self-contained blocks(독립적으로 실행 가능한 블록코드) 를정의해 비동기 작업을 다루고, Combine은 이벤트 스트림이라는 개념을 이용한다. Async-await은 새롭게 등장한 비동기 코드 방식으로 가독성과 유지보수성이 높은 코드를 작성 할 수 있다고 함.
URLSession을 활용하는 비동기 코드 예제이다.
Closure - 선언
func queryByFood(
name:String,
result: @escaping(MealsList?, FoodError?) -> ()
) {
let path = "<https://www.exampels.com/api/json/s=\\(name)>"
let request = URLRequest(url: URL(String: path)!)
URLSession.shared.dataTask(with: request) { data,response,error in
if let data = data {
if let list = try? JSONDecoder().decode(MealList.self, from: data){
result(list,nil)
} else { result(nil,.decoding)
} else { result(nil, .unknown(error?.locallizedDescription))
}
}
Combine - 선언
func queryByFood(name: String) -> AnyPublisher<MealList, FoodError> {
let path = "<https://www.examples/com/api/json/s=\\(name)>"
let requets = URLRequest(url: URL(string:path)!)
return URLSession.shared.dataTaskPublisher(for: request)
.map(\\.data)
.decode(type: MealList.self, decoder: JSONDecoder())
.mapError { FoodError.unknown($0.locallizedDescription }
.eraseToAnyPublisher()
}
Async / Await - 선언
func queryByFood(name:String) async throws -> MealList {
let path = "<https://www.examples/com/api/json/s=\\(name)>"
let request = URLRequest(url: URL(string:path)!)
let (data,_) = try await URLSession.shared.data(for:request)
return try JSONDecoder().decode(MealList.Self, from:data)
}
Closures - 호출부
func load(food:String) {
queryByFood(name:food) { list, error in
DispatchQeue.main.async {
}
}
}
Combine - 호출부
func load(food:String) {
queryByName(name:food)
.flatMap{ .....logic }
.recevie(on:DispatchQueue.main)
.sink { .....some logic }
.store(in: &cancellables)
}
Async/Await
@MainActor
func load(food:String) {
Task {
do {
restults = try await queryByFood(name:food)
'''''some logic '''''
} catch { self.error = error.localizedDescription }
}
}