Future
비동기적으로 하나의 결과를 생성하고, completion 이벤트를 발행하는 Publisher
값이 아직 존재하지 않는 맥락을 나타낸다.
일반적으로 비동기 함수의 콜백 메서드, completion 핸들러를 대신하기위해 사용한다.
오래걸리는 비동기작업을 구독할 경우, subscription 을 따로 저장해두는 것이 좋다.
저장해두지 않으면 현재 scope 를 떠나자마자 구독이 취소되기 때문.
내부 코드
final public class Future<Output, Failure> : Publisher
where Failure: Error {
public typealias Promise = (Result<Output, Failure>) -> Void
...
}
Swift
복사
•
Promise
Promise 는 미래의 결과물을 나타낸다.
Promise 는 Result 타입을 파라미터로 받는 클로져이다.
Result 는 Future 로부터 발행된 값을 갖고 있거나, 에러를 담고있게 된다.
•
전달된 클로져는 즉시 실행된다.
여타 다른 퍼블리셔와는 달리 subscriber 를 달아주지 않아도 즉시 실행된다.
생성 방법.
Future<Int, Never> { promise in
DispatchQueue.global().asyncAfter(deadline: .now() + delay) {
promise(.success(integer + 1))
}
}
Swift
복사
Escaping Closure 구문을 Future Publisher 코드로 변경하기
func getEscapingClosuer(completion: @escaping (_ value: String, _ error: Error?) -> ()) {
URLSession.shared.dataTask(with: url) { data, response, error in
completion("New value 2", nil)
}
.resume()
}
Swift
복사
class FutureViewModel: ObservableObject {
@Published var title: String = "Hello"
let url = URL(string: "https://www.google.com")!
var cancellables = Set<AnyCancellable>()
init() {
download()
}
func download() {
//퍼블리셔 호출
getFuturePublisher()
.sink { completion in
} receiveValue: { [weak self] value in
self?.title = value
print(value)
}
.store(in: &cancellables)
}
//퍼블리셔 전환 코드
func getFuturePublisher() -> Future<String, Error> {
Future { promise in
self.getEscapingClosure { value, error in
if let error = error {
promise(.failure(error))
} else {
promise(.success(value))
}
}
}
}
//completion 핸들러
func getEscapingClosure(completion: @escaping (_ value: String, _ error: Error?) -> ()) {
URLSession.shared.dataTask(with: url) { data, response, error in
completion("New value 2", nil)
}
.resume()
}
}
let vm = FutureViewModel()
Swift
복사