Skip to content

Instantly share code, notes, and snippets.

@EricRabil
Created July 19, 2021 20:19
Show Gist options
  • Select an option

  • Save EricRabil/3743bcba37fe0090078cca3dfeea8a7e to your computer and use it in GitHub Desktop.

Select an option

Save EricRabil/3743bcba37fe0090078cca3dfeea8a7e to your computer and use it in GitHub Desktop.
Swift Combine – Future vs. DeferredFuture
//
// main.swift
//
// Created by Eric Rabil on 7/19/21.
//
import Foundation
import Combine
public class DeferredFuture<Output, Failure> : Publisher where Failure : Error {
/// A type that represents a closure to invoke in the future, when an element or error is available.
///
/// The promise closure receives one parameter: a `Result` that contains either a single element published by a ``Future``, or an error.
public typealias Promise = (Result<Output, Failure>) -> Void
private let pending: Deferred<Future<Output, Failure>>
/// Creates a publisher that invokes a promise closure when the publisher emits an element.
///
/// - Parameter attemptToFulfill: A ``Future/Promise`` that the publisher invokes when the publisher emits an element or terminates with an error.
public init(_ attemptToFulfill: @escaping (@escaping Future<Output, Failure>.Promise) -> Void) {
pending = Deferred {
Future(attemptToFulfill)
}
}
/// Attaches the specified subscriber to this publisher.
///
/// Implementations of ``Publisher`` must implement this method.
///
/// The provided implementation of ``Publisher/subscribe(_:)-4u8kn``calls this method.
///
/// - Parameter subscriber: The subscriber to attach to this ``Publisher``, after which it can receive values.
final public func receive<S>(subscriber: S) where Output == S.Input, Failure == S.Failure, S : Subscriber {
pending.receive(subscriber: subscriber)
}
}
let future = Future<Void, Error> { completion in
print("i execute immediately")
}
print("i execute second")
let deferredFuture = DeferredFuture<Void, Never> { completion in
print("i execute fourth")
completion(.success(()))
}
print("i execute third")
let sub = deferredFuture.sink {
print("i execute fifth")
}
print("i execute sixth")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment