Future - wurzelsand/swift-memos GitHub Wiki
Future
- Subscriptions speichern
Erzeuge einen Publisher future
der nach einer Sekunde Verzögerung den String "Hello World" veröffentlicht. Trage zwei Subscriber für future
ein.
import Foundation
import Combine
let future = Future<String, Never> { promise in
print("Start closure")
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
promise(.success("Hello World"))
}
}
print("Go")
var subscriptions = [AnyCancellable]()
future
.sink(receiveCompletion: { print("completion:", $0) }, receiveValue: { print("First:", $0) })
.store(in: &subscriptions)
future
.sink { print("Second:", $0) }
.store(in: &subscriptions)
RunLoop.main.run(until: Date(timeIntervalSinceNow: 2))
Ausgabe:
Start closure
Go
Second: Hello World
First: Hello World
completion: finished
Program ended with exit code: 0
-
Sobald
future
deklariert wird, wird sein Closure gestartet, nicht erst wenn sich ein Subscriber als Abonnent einschreibt. -
Ich speichere die Abonnements in einem Array aus
AnyCancellable
. -
Sobald im Closure
promise(.success())
oderpromise(.failure())
aufgerufen wird, kümmert sich dasFuture
-Objekt darum, dass dasResult
veröffentlicht wird und ignoriert alle weiterenResults
. Ich stelle mir das in etwa so vor:typealias Promise = (Result<Int, Error>) -> Void class Future { let promise: Promise = { var finished = false return { result in if finished { return } switch result { case .failure(let error): print("failure:", error) case .success(let value): print("publishing value:", value) } finished = true } }() init(handler: (Promise) -> Void) { handler(self.promise) } } let future = Future { promise -> Void in for i in 1...3 { print(i) promise(.success(i)) } }
Ausgabe:
1 publishing value: 1 2 3
Ein
Future
-Objekt stelle ich also her, indem ich ihm eine Funktion übergebe, die einen einzelnen Parameter benötigt, um aufgerufen zu werden. Diesen Parameter stellt mir dasFuture
-Objekt zur Verfügung. Ich selber kann diesen Parameter in meiner Funktion verwenden. Bei dem Parameter, das mir dasFuture
-Objekt zur Verfügung stellt, handelt es sich um eine Funktion, die ich mit einem beliebigenResult
als Parameter aufrufen kann. Was dieser Aufruf bewirkt, liegt in der Verantwortung desFuture
-Objekts: Es sendet entweder einen Wert (bei.success(value)
) oder einen Fehler (bei.failure(error)
) an seine Subscriber.