Future
public final class Future<Value> : AnyFuture
extension Future: Equatable
Container for a result that will be provided later.
Functions that promise to do work asynchronously return a Future<Value>
. The receipient of a future can
observe it to be notified, or to queue more asynchronous work, when the operation completes.
A Future<Value>
is regarded as:
resolved
, when a value is setfulfilled
, when a value is set and successfulrejected
, when a value is not set, and an error occured
The provider of a Future<Value>
creates a placeholder object before the actual result is available,
immeadiately returning the object, providing a dynamic way of structuring complex dependencies
for asynchronous work. This is common behavior in Future/Promise implementation across many languages.
Referencing these resources may be useful if you’re unfamilliar with the concept of Promises/Futures:
The provider of a Future<Value>
may be implemented as follows:
func performAsynchronousWork() -> Future<String> {
let promise = Promise<String>()
DispatchQueue.global().async {
... on success ...
promise.fulfill("A string")
... on failure ...
promise.reject(error)
}
return promise.future
}
When receiving a Future<Value>
, you have a number of options. You can immediately observe the result of the future
using whenResolved()
, whenFulfilled()
, or whenRjected()
, or choose to do more asyncrhonous work before, or
parallel to observing.
Each Future<Value>
can have multiple observers, which are used to both simply return
a result, or to queue up other futures.
To perform more asynchronous work, once a Future<Value>
is fulfilled,
use flatMap()
. To transform the fulfilled value of a future into another value, use flatMapThrowing()
.
Options for combining futures into a single future is provided using and()
, fold()
, and Future<Value>.reduce()
A Future<Value>
differs from a Promise<Value>
in that a future is the
container of a result; the promise being the function that sets that result.
This design decision was made, in this library as well as in many others, to
prevent receivers of Future<Value>
to resolve the future themselves.
-
Creates a pending future
Declaration
Swift
public init()
-
Creates a resolved future
Declaration
Swift
public init(resolved: Result<Value, Error>)
Parameters
resolved
Result<Value, Error>
-
Creates a resolved, fulfilled future
Declaration
Swift
public convenience init(fulfilledWith value: Value)
Parameters
value
Value of the fulfilled future
-
Creates a resolved, fulfilled future
Declaration
Swift
public convenience init(rejectedWith error: Error)
Parameters
error
Error, rejecting the future
-
Indicates whether the future is pending
Declaration
Swift
public var isPending: Bool { get }
-
Indicates whether the future is resolved
Declaration
Swift
public var isResolved: Bool { get }
-
Indicates whether the future is fulfilled
Declaration
Swift
public var isFulfilled: Bool { get }
-
Indicates whether the future is rejected
Declaration
Swift
public var isRejected: Bool { get }
-
Indicates the result of the future. Returns
nil
if the future is not resolved yet.Declaration
Swift
public var result: Result<Value, Error>? { get }
-
Declaration
Swift
public static func == (lhs: Future, rhs: Future) -> Bool
-
When the current
Future
is fulfilled, run the provided callback returning a newFuture<Value>
.This allows you to dispatch new asynchronous operations as steps in a sequence of operations. Note that, based on the result, you can decide what asynchronous work to perform next.
This function is best used when you have other APIs returning
Future<Value>
.Declaration
Swift
func flatMap<NewValue>( on queue: DispatchQueue = .futures, callback: @escaping (_ value: Value) -> Future<NewValue>) -> Future<NewValue>
Parameters
queue
DispatchQueue on which to resolve and return a new future. Defaults to
DispatchQueue.futures
.callback
A function that will receive the value of this
Future
and return a newFuture<Value>
.value
The fulfilled value of this
Future<Value>
.Return Value
A future that will receive the eventual value.
-
When the current
Future
is rejected, run the provided callback reurning a newFuture<Value>
.This allows you to proceed with some other operation if the current
Future
was rejected, due to an error you can recover from.If the calback cannot provide a
Future
recovering from the error, an error inside the callback should be thrown, or aFuture
which is rejected should be returned.Declaration
Swift
func flatMapIfRejected( on queue: DispatchQueue = .futures, callback: @escaping(Error) -> Future<Value>) -> Future<Value>
Parameters
queue
DispatchQueue on which to resolve and return a new future. Defaults to
DispatchQueue.futures
.callback
A function that will receive the error resulting in this
Future<Value>
s rejection.Return Value
A future that will receive the eventual value.
-
When the current
Future
is fulfilled, run the provided callback returning a fulfilled value of theFuture<NewValue>
returned by this method.If the calback cannot provide a a new value, an error inside the callback should be thrown.
Declaration
Swift
func flatMapThrowing<NewValue>( on queue: DispatchQueue = .futures, callback: @escaping (Value) throws -> NewValue) -> Future<NewValue>
Parameters
queue
DispatchQueue on which to resolve and return a new value. Defaults to
DispatchQueue.futures
.callback
A function that will receive the value of this
Future
and return a newFuture<Value>
. Throwing an error in this function will result in the rejection of the returnedFuture<Value>
.Return Value
A future that will receive the eventual value.
-
When the current
Future
is fulfilled, run the provided callback returning a fulfilled value of theFuture<NewValue>
returned by this method.Declaration
Swift
func map<NewValue>( on queue: DispatchQueue = .futures, callback: @escaping (Value) -> NewValue) -> Future<NewValue>
Parameters
queue
DispatchQueue on which to resolve and return a new value. Defaults to
DispatchQueue.futures
.callback
A function that will receive the value of this
Future
and return a newFuture<Value>
Return Value
A future that will receive the eventual value.
-
When the current
Future
is fulfilled, run the provided callback returning a fulfilled value of theFuture<NewValue>
returned by this method.Declaration
Swift
func map<NewValue>( _ keyPath: KeyPath<Value, NewValue>, on queue: DispatchQueue = .futures) -> Future<NewValue>
Parameters
queue
DispatchQueue on which to resolve and return a new value. Defaults to
DispatchQueue.futures
.keyPath
A
KeyPath<Value, NewValue>
pointing to a value to return on the receivingFuture<Value>
.Return Value
A future that will receive the eventual value.
-
When the current
Future
is rejected, run the provided callback returning a fulfilled value of theFuture<NewValue>
returned by this method.This allows you to provide a future with an eventual value if the current
Future
was rejected, due to an error you can recover from.Declaration
Swift
func recover(on queue: DispatchQueue = .futures, callback: @escaping (Error) -> Value) -> Future<Value>
Parameters
queue
DispatchQueue on which to resolve and return a new value. Defaults to
DispatchQueue.futures
.callback
A function that will receive the value of this
Future<Value>
, and return a new value of typeNewValue
.Return Value
A future that will receive the eventual value.
-
Undocumented
Declaration
Swift
func mapIfRejected(on queue: DispatchQueue = .futures, callback: @escaping (Error) -> Value) -> Future<Value>
-
Returns a new
Future
, that resolves when this and the provided future both are resolved. The returned future will provide the pair of values from this and the provided future.Note that the returned future will be rejected with the first error encountered.
Declaration
Swift
func and<NewValue>(_ other: Future<NewValue>, on queue: DispatchQueue = .futures) -> Future<(Value, NewValue)>
Parameters
other
A
Future
to combine with this future.queue
Dispatch queue to observe on.
Return Value
A future that will receive the eventual value.
-
Returns a new
Future<Value>
that fires only when thisFuture<Value>
and all providedFuture<NewValue>
s complete.A combining function must be provided, resulting in a new future for any pair of
Future<NewValue>
andFuture<Value>
eventually resulting in a singleFuture<Value>
.The returned
Future<Value>
will be rejected as soon as either this, or a provided future is rejected. However, a failure will not occur until all precedingFuture
s have been resolved. As soon as a rejection is encountered, there subsequent futures will not be waited for, resulting in the fastest possible rejection for the provided futures.Declaration
Swift
func fold<NewValue, S: Sequence>( _ futures: S, on queue: DispatchQueue = .futures, with combiningFunction: @escaping (Value, NewValue) -> Future<Value>) -> Future<Value> where S.Element == Future<NewValue>
Parameters
futures
A sequence of
Future<NewValue>
to wait for.queue
Dispatch queue to observe on.
combiningFunction
A function that will be used to fold the values of two
Future
s and return a new value wrapped in anFuture
.Return Value
A future that will receive the eventual value.
-
Returns a new
Future<Value>
that fires only when all the providedFuture<NewValue>
s have been resolved. The returned future carries the value of theinitialResult
provided, combined with the result of fulfilledFuture<NewValue>
s using the providednextPartialResult
function.The returned
Future<Value>
will be rejected as soon as either this, or a provided future is rejected. However, a failure will not occur until all precedingFuture
s have been resolved. As soon as a rejection is encountered, there subsequent futures will not be waited for, resulting in the fastest possible rejection for the provided futures.Declaration
Swift
static func reduce<NewValue, S: Sequence>( _ futures: S, on queue: DispatchQueue = .futures, initialResult: Value, nextPartialResult: @escaping (Value, NewValue) -> Value) -> Future<Value> where S.Element == Future<NewValue>
Parameters
futures
A sequence of
Future<NewValue>
to wait for.queue
Dispatch queue to observe on.
initialResult
An initial result to begin the reduction.
nextPartialResult
The bifunction used to produce partial results.
Return Value
A future that will receive the reduced value.
-
Returns a new
Future<Value>
that will resolve with result of thisFuture
after the providedFuture<Void>
has been resolved.Note that the provided callback is called regardless of whether this future is fulfilled or rejected. The returned
Future<Value>
is fulfilled only if this and the provided future both are fullfilled.In short, the returned future will forward the result of this future, if the provided future is fulfilled.
Declaration
Swift
func always(on queue: DispatchQueue = .futures, callback: @escaping () -> Future<Void>) -> Future<Value>
Parameters
queue
Dispatch queue to observe on.
initialResult
An initial result to begin the reduction.
callback
A callback that returns a
Future<Void>
to be deferred.Return Value
A future that will receive the eventual value.
-
Returns a new
Future<Value>
that will resolve with the result of thisFuture
after the provided callback runs.Note that the provided callback is called regardless of whether this future is fulfilled or rejected.
This method is useful for times you want to execute code at the end of a chain of operations, regarless of whether successful or not.
Declaration
Swift
func alwaysThrowing(on queue: DispatchQueue = .futures, callback: @escaping () throws -> Void) -> Future<Value>
Parameters
queue
Dispatch queue to observe on.
callback
Callback to run.
Return Value
A future that will receive the eventual value.
-
Returns a new Future
, effectively discarding the result of the caller. This method is useful when the value of a future is of no consequence.
Declaration
Swift
@discardableResult func discard(on queue: DispatchQueue = .futures) -> Future<Void>
Parameters
queue
Dispatch queue to discard on.
Return Value
A future that will receive the eventual value.
-
Adds a
FutureObserver<Value>
to thisFuture<Value>
, that is called when the future is fulfilled.An observer callback cannot return a value, meaning that this function cannot be chained from. If you are attempting to create a sequence of operations based on the result of another future, consider using
flatMap()
,flatMapThrowing()
, or some of the other methods available.Declaration
Swift
@discardableResult func whenFulfilled( on queue: DispatchQueue = .futures, callback: @escaping (Value) -> Void) -> FutureObserver<Value>
Parameters
queue
Dispatch queue to observe on.
callback
Callback invoked with the fulfilled result of this future
Return Value
A
FutureObserver<Value>
, which can be used to remove the observer from this future. -
Adds a
FutureObserver<Value>
to thisFuture<Value>
, that is called when the future is rejected.An observer callback cannot return a value, meaning that this function cannot be chained from. If you are attempting to create a sequence of operations based on the result of another future, consider using
flatMap()
,flatMapThrowing()
, or some of the other methods available.Declaration
Swift
@discardableResult func whenRejected( on queue: DispatchQueue = .futures, callback: @escaping (Error) -> Void) -> FutureObserver<Value>
Parameters
queue
Dispatch queue to observe on.
callback
Callback invoked with the rejection error of this future
Return Value
A
FutureObserver<Value>
, which can be used to remove the observer from this future. -
Adds a
FutureObserver<Value>
to thisFuture<Value>
, that is called when the future is resolved.An observer callback cannot return a value, meaning that this function cannot be chained from. If you are attempting to create a sequence of operations based on the result of another future, consider using
flatMap()
,flatMapThrowing()
, or some of the other methods available.Declaration
Swift
@discardableResult func whenResolved( on queue: DispatchQueue = .futures, callback: @escaping (Result<Value, Error>) -> Void) -> FutureObserver<Value>
Parameters
queue
Dispatch queue to observe on.
callback
Callback invoked with the resolved
Result<Value, Error>
of this futureReturn Value
A
FutureObserver<Value>
, which can be used to remove the observer from this future.