Promise

public final class Promise<T>

Overview

DeLorean is a lightweight framework which allows you to write better async code in Swift. We designed DeLorean to be simple to use and also very flexible. It’s partially based on JavaScript A+ specs. We have added some useful features like progressable and cancellable promises. This promises layer queues all async task on background to avoid block the main thread.

  • Creates an instant pending Promise

    Declaration

    Swift

    public init()
  • Creates an instant fulfilled Promise

    Declaration

    Swift

    public init(value: T)
  • Creates an instant rejected Promise

    Declaration

    Swift

    public init(error: Error)
  • Creates a Promise with block-based api

    Declaration

    Swift

    public init(context: Executer = DispatchQueue.global(qos: .userInitiated),
                resolvers: @escaping
        (
        _ progress: @escaping(T) -> Void,
        _ fulfill: @escaping (T) -> Void,
        _ reject: @escaping (Error) -> Void,
        _ cancelled: @escaping () -> Void) throws -> Void)

    Parameters

    resolvers

    Multiples blocks to handle the future state of promise

    Return Value

    The new Promise instance.

  • Creates a Promise with enum-based DSL

    Declaration

    Swift

    public init(context: Executer = DispatchQueue.global(qos: .userInitiated),
                future: @escaping ( @escaping (Future<T>) -> Void) throws -> Void)

    Parameters

    future

    Future value-type to handle the future state of promise

    Return Value

    The new Promise instance.

  • Progress

    If there is an asynchronous action that can succeed more than once, or delivers a series of values over time instead of just one, but you don’t want to finish the promise you can use this function.

    let foobar = Promise<Int> { future in
        future(.progress(0))
        future(.progress(1))
        future(.progress(2))
        future(.fulfill(3))
        }.progress({ value in
            // This block is called multiple times
            print(value)
        }).then({ value in
            // This block is called once
            print(value)
        })
    

    Declaration

    Swift

    public func progress(on context: Executer = DispatchQueue.main,
                         _ progressed: @escaping (T) -> Void) -> Promise<T>
  • Map for chaineable promises

    Declaration

    Swift

    public func then<U>(on context: Executer = DispatchQueue.main,
                        _ transform: @escaping (T) throws -> Promise<U>) -> Promise<U>
  • FlatMap for chaineable promises

    Declaration

    Swift

    public func then<U>(on context: Executer = DispatchQueue.main,
                        _ transform: @escaping (T) throws -> U) -> Promise<U>
  • Then

    You can simple chaining multiple asynchronous tasks.

    let foobar = Promise { future in
        future(.fulfill("foobar"))
    }
    
    promise.then { value in
        print(value)
    }
    

    Declaration

    Swift

    public func then(on context: Executer = DispatchQueue.main,
                     _ fulfilled: @escaping (T) -> Void,
                     _ rejected: @escaping (Error) -> Void = { _ in },
                     _ progressed: @escaping (T) -> Void = { _ in },
                     _ cancelled: @escaping () -> Void = { }) -> Promise<T>
  • Cancel

    This function will trigger a callback that the promise can use to cancel its work. Naturally, requesting cancellation of a promise that has already been resolved does nothing, even if the callbacks have not yet been invoked.

    let foobar = Promise<Int> { future in
        future(.progress(0))
        future(.cancel)
        future(.fulfill(3))
        }.progress {
            print($0)
        }.cancel {
            // Handle cancellable work
        }.then { value in
            // This block is never called
            print(value)
    }
    

    Declaration

    Swift

    public func cancel(on context: Executer = DispatchQueue.main,
                       _ cancelled: @escaping () -> Void) -> Promise<T>
  • Returns if promise state is pending

    Declaration

    Swift

    public var isPending: Bool
  • Returns if promise state is fulfilled

    Declaration

    Swift

    public var isFulfilled: Bool
  • Returns if promise state is rejected

    Declaration

    Swift

    public var isRejected: Bool
  • Returns if promise state is cancelled

    Declaration

    Swift

    public var isCancelled: Bool
  • Returns current value of promise

    Declaration

    Swift

    public var value: T?
  • Returns current error of promise

    Declaration

    Swift

    public var error: Error?
  • Update promise state synchronous to progressed

    Declaration

    Swift

    public func progress(_ value: T)
  • Update promise state synchronous to fulfilled

    Declaration

    Swift

    public func fulfill(_ value: T)
  • Update promise state synchronous to rejected

    Declaration

    Swift

    public func reject(_ error: Error)
  • Update promise state synchronous to cancelled

    Declaration

    Swift

    public func cancel()
  • Recover

    This function lets us catch an error and easily recover from it without breaking the rest of the promise chain.

    let foobar = Promise<Int> { _ in
       throw SimpleError()
    }.recover { error in
       return Promise(value: 0)
    }.then {
       print($0)
    }.catch {
       // Handle error
    }
    

    Declaration

    Swift

    public func recover(_ recovery: @escaping (Error) throws -> Promise<T>) -> Promise<T>
  • Zip

    This function allows you to join different promises 2 and return a tuple with the result of them. Promises are resolved in parallel.

     let promise1 = Promise(value: 0)
     let promise2 = Promise(value: "foobar")
     let zipped = Promise<Void>.zip(promise1, promise2)
         .then { value1, value2 in
             print(value1) // This function prints `0`
             print(value2) // This function prints `"foobar"`
    }
    

    Declaration

    Swift

    public static func zip<T, U>(_ first: Promise<T>,
                                 _ second: Promise<U>) -> Promise<(T, U)>
  • Zip

    This function allows you to join different promises 3 and return a tuple with the result of them. Promises are resolved in parallel.

    let promise1 = Promise(value: 0)
    let promise2 = Promise(value: "foo")
    let promise3 = Promise(value: "bar")
    let zipped = Promise<Void>.zip(promise1, promise2, promise3)
       .then { value1, value2, value3 in
           print(value1) // This function prints `0`
           print(value2) // This function prints `"foo"`
           print(value3) // This function prints `"bar"`
    }
    

    Declaration

    Swift

    public static func zip<T1, T2, T3>(_ first: Promise<T1>,
                                       _ second: Promise<T2>,
                                       _ last: Promise<T3>) -> Promise<(T1, T2, T3)>
  • Zip

    This function allows you to join different promises 4 and return a tuple with the result of them. Promises are resolved in parallel.

     let promise1 = Promise(value: 0)
     let promise2 = Promise(value: "foo")
     let promise3 = Promise(value: "bar")
     let promise4 = Promise(value: true)
     let zipped = Promise<Void>.zip(promise1, promise2, promise3, promise4)
            .then { value1, value2, value3 in
                print(value1) // This function prints `0`
                print(value2) // This function prints `"foo"`
                print(value3) // This function prints `"bar"`
                print(value4) // This function prints `true`
     }
    

    Declaration

    Swift

    public static func zip<T1, T2, T3, T4>(_ first: Promise<T1>,
                                           _ second: Promise<T2>,
                                           _ third: Promise<T3>,
                                           _ last: Promise<T4>) -> Promise<(T1, T2, T3, T4)>
  • Timeout

    Timeout allows us to wait for a promise for a time interval or reject it, if it doesn’t resolve within the given time. The interval is expresed in seconds.

    let promise = Promise<Int> { future in
        future(.fulfill(5))
        }.timeout(0.5)
    

    Declaration

    Swift

    public func timeout(_ timeout: TimeInterval) -> Promise<T>
  • Timeout

    Static implementation for timeout. The interval is expresed in seconds.

    Promise<Void>.timeout(0.2).then {
       // do something
    }
    

    Declaration

    Swift

    public static func timeout<T>(_ timeout: TimeInterval) -> Promise<T>
  • Delay

    Defer the execution of a Promise by a given time interval.

    let promise = Promise<Void>.delay(0.2).then {
       // do something
    }
    

    Declaration

    Swift

    public static func delay(_ delay: TimeInterval) -> Promise<Void>
  • Race

    This function race many asynchronous promises and return the value of the first to complete.

    let promise1 = Promise(value: 1)
    let promise2 = Promise(value: 2)
    let promise3 = Promise(value: 3)
    let promise4 = Promise(value: 4)
    
    let promise = Promise<Int>
       .race([promise1, promise2, promise3, promise4])
       .then { fastValue in
           print(fastValue)
    }
    

    Declaration

    Swift

    public static func race<T>(on context: Executer = DispatchQueue.main, _ promises: [Promise<T>]) -> Promise<T>
  • Always

    This function allows you to specify a block which will be always executed both for fulfill and reject of the Promise.

    let foobar = Promise<Int> { _ in
        throw SimpleError()
    }.then {
       print($0)
    }.catch {
       // Handle error
    }.always {
       // This block is always called
    }
    

    Declaration

    Swift

    public func always(on context: Executer = DispatchQueue.main,
                       _ completion: @escaping () -> Void) -> Promise<T>
  • Validate

    Validate is a function that takes a predicate, and rejects the promise chain if that predicate fails.

    let promise = Promise(value: 2)
        .validate { $0 == 3 }
        .catch { error in
            // This promise always fails
    }
    

    Declaration

    Swift

    public func validate(_ predicate: @escaping (T) -> Bool) -> Promise<T>
  • Retry

    Retry operator allows you to execute source chained promise if it ends with a rejection. If reached the attempts the promise still rejected chained promise is also rejected along with the same source error.

     let promise = Promise<Int>
         .retry(attempt: 3) { () -> Promise<Int> in
             guard threshold != 1 else { return Promise(value: 8) }
             threshold -= 1
             return Promise(error: SimpleError())
     }
    

    Declaration

    Swift

    public static func retry<T>(attempt: Int,
                                delay: TimeInterval = 0,
                                generate: @escaping () -> Promise<T>) -> Promise<T>
  • Catch

    This function allows you to handle Promise’s errors. The operator itself implicitly returns another promise, that is rejected with the same error.

    let foobar = Promise<Void> { future in
       future(.reject(SimpleError()))
    }.then({ value in
       print(value)
    }).catch({ error in
       // Handle simple error here
    })
    

    Declaration

    Swift

    public func `catch`(on queue: Executer = DispatchQueue.main,
                        _ rejected: @escaping (Error) -> Void) -> Promise<T>
  • All

    This function create a Promise that resolved when the list of passed Promises resolves (promises are resolved in parallel). Promise also reject as soon as a promise reject for any reason.

     let promise1 = Promise(value: 1)
     let promise2 = Promise(value: 2)
     let promise3 = Promise(value: 3)
     let promise4 = Promise(value: 4)
    
     let promise = Promise<Int>
         .all([promise1, promise2, promise3, promise4])
         .then { values in
             for number in values {
                 print(number)
             }
     }
    

    Declaration

    Swift

    public static func all<T>(_ promises: [Promise<T>]) -> Promise<[T]>