Future - wurzelsand/swift-memos GitHub Wiki

Future

Themen

  • Future
  • Subscriptions speichern

Aufgabe

Erzeuge einen Publisher future der nach einer Sekunde Verzögerung den String "Hello World" veröffentlicht. Trage zwei Subscriber für future ein.

Ausführung

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

Anmerkung

  • 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()) oder promise(.failure()) aufgerufen wird, kümmert sich das Future-Objekt darum, dass das Result veröffentlicht wird und ignoriert alle weiteren Results. 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 das Future-Objekt zur Verfügung. Ich selber kann diesen Parameter in meiner Funktion verwenden. Bei dem Parameter, das mir das Future-Objekt zur Verfügung stellt, handelt es sich um eine Funktion, die ich mit einem beliebigen Result als Parameter aufrufen kann. Was dieser Aufruf bewirkt, liegt in der Verantwortung des Future-Objekts: Es sendet entweder einen Wert (bei .success(value)) oder einen Fehler (bei .failure(error)) an seine Subscriber.

⚠️ **GitHub.com Fallback** ⚠️