@escaping closure는 Combine Framework이 나오기 전에 비동기를 처리하던 방식
class FuturesBootcampViewModel: ObservableObject {
@Published var title: String = "Starting title"
let url = URL(string: "https://www.google.com")!
var cancellables = Set<AnyCancellable>()
init() {
download()
}
func download() {
getCombinePublisher()
.sink { _ in
} receiveValue: { [weak self] returnedValue in
self?.title = returnedValue
}
.store(in: &cancellables)
}
func getCombinePublisher() -> AnyPublisher<String, URLError> {
URLSession.shared.dataTaskPublisher(for: url)
.timeout(1, scheduler: DispatchQueue.main)
.map({ _ in
return "New value"
})
.eraseToAnyPublisher()
}
}
요런 flow가 있다고 해봅시다
func getEscapingClosure(completionHandler: @escaping (_ value: String, _ error: Error?) -> ()) {
URLSession.shared.dataTask(with: url) { data, response, error in
completionHandler("New Value2", nil)
}
.resume()
}
예전에는 요런식으로 dataTask가 처리되고 나면 처리된 결과 자체를 handler에 담아서 다른 스코프에서 또 처리를 해주는 식으로 @escaping closure를 처리해줬습니다
오늘 해볼건 @escaping으로 처리된 애가 Publisher로 바뀔 수 있느냐!
Future라는 Publisher를 사용하면 됩니다
Future의 자동완성을 해보면 Promise라는 키워드도 있는 걸 볼 수 있는데 결과가 약속 되어 있다고 생각하면 됨
아직 값은 없지만 어떠한 결과가 나올 것이라고 약속을 해주는 거
func getFuturePublisher() -> Future<String, Error> {
Future { promise in
self.getEscapingClosure { returnedValue, error in
if let error = error {
promise(.failure(error))
} else {
promise(.success(returnedValue))
}
}
}
}
Future 퍼블리셔를 반환하는 메소드는 요런 형식이 되겠다!
escaping으로 처리되던 결과 값을 퍼블리싱 해주게 되는거!!
일반적으로 비동기 task는 지금처럼 즉시 반환해주는 return을 할 수가 없음
요렇게 completion에다가 @escaping으로 넣어줘야하죠?
이런식으로 작성하는 겁니다!!
예전에 사용하던 비동기 처리 방식인 @escaping 의 결과 값들을
Future라는 Publisher를 이용해서 Combine Framework으로 바꿔줄 수 있는 거!!