CoFuture
Holder for a result that will be provided later.
CoFuture
and its subclass CoPromise
are the implementation of the Future/Promise approach.
They allow to launch asynchronous tasks and immediately returnCoFuture
with its future results.
The available result can be observed by the whenComplete()
callback
or by await()
inside a coroutine without blocking a thread.
func makeFutureOne(args) -> CoFuture<Response> {
let promise = CoPromise<Response>()
someAsyncFuncWithCallback { response in
. . . do some work . . .
promise.success(response)
}
return promise
}
func makeFutureTwo(args) -> CoFuture<Response> {
queue.coroutineFuture {
let future = makeFutureOne(args)
. . . do some work . . .
let response = try future.await()
. . . create result using response . . .
return result
}
}
func performSomeWork(args) {
let future = makeFutureTwo(args)
mainQueue.startCoroutine {
. . . do some work . . .
let result = try future.await()
. . . do some work using result . . .
}
}
For coroutine error handling you can use standart do-catch
statement or use CoFuture
as an alternative.
//execute coroutine and return CoFuture<Void> that we will use for error handling
DispatchQueue.main.coroutineFuture {
let result = try makeSomeFuture().await()
. . . use result . . .
}.whenFailure { error in
. . . handle error . . .
}
Apple has introduced a new reactive programming framework Combine
that makes writing asynchronous code easier and includes a lot of convenient and common functionality.
We can use it with coroutines by making CoFuture
a subscriber and await its result.
//create Combine publisher
let publisher = URLSession.shared.dataTaskPublisher(for: url).map(\.data)
//execute coroutine on the main thread
DispatchQueue.main.startCoroutine {
//subscribe CoFuture to publisher
let future = publisher.subscribeCoFuture()
//await data without blocking the thread
let data: Data = try future.await()
}
-
Initializes a future that invokes a promise closure.
func someAsyncFunc(callback: @escaping (Result<Int, Error>) -> Void) { ... } let future = CoFuture(promise: someAsyncFunc)
Declaration
Swift
@inlinable public convenience init(promise: (@escaping (Result<Value, Error>) -> Void) -> Void)
Parameters
promise
A closure to fulfill this future.
-
Starts a new coroutine and initializes future with its result.
Note
If you cancel thisCoFuture
, it will also cancel the coroutine that was started inside of it.func sum(future1: CoFuture<Int>, future2: CoFuture<Int>) -> CoFuture<Int> { CoFuture { try future1.await() + future2.await() } }
Declaration
Swift
@inlinable public convenience init(task: @escaping () throws -> Value)
Parameters
task
The closure that will be executed inside the coroutine.
-
Initializes a future with result.
Declaration
Swift
@inlinable public convenience init(result: Result<Value, Error>)
Parameters
result
The result provided by this future.
-
Returns completed result or nil if this future has not been completed yet.
Declaration
Swift
public var result: Result<Value, Error>? { get }
-
Returns
true
when the current future is canceled.Declaration
Swift
@inlinable public var isCanceled: Bool { get }
-
Cancels the current future.
Declaration
Swift
public func cancel()
-
Await for the result of this
CoFuture
without blocking the current thread. Must be called inside a coroutine.//execute someSyncFunc() on global queue and return its future result let future = DispatchQueue.global().coroutineFuture { someSyncFunc() } //start coroutine on main thread DispatchQueue.main.startCoroutine { //await result of future let result = try future.await() }
Throws
The failed result of theCoFuture
.Declaration
Swift
@inlinable public func await() throws -> Value
Return Value
The value of the
CoFuture
when it is completed. -
Await for the result of this
CoFuture
without blocking the current thread. Must be called inside a coroutine.Throws
The failed result of theCoFuture
.Declaration
Swift
public func await(timeout: DispatchTimeInterval) throws -> Value
Parameters
timeout
The time interval to await for a result.
Return Value
The value of the
CoFuture
when it is completed.
-
When future is fulfilled, run the provided callback, which performs a synchronous computation and return transformed value.
Declaration
Swift
@inlinable public func map<NewValue>(_ transform: @escaping (Value) throws -> NewValue) -> CoFuture<NewValue>
Parameters
transform
Function that will receive the value and return a new transformed value or throw an error.
Return Value
A future that will receive the eventual value.
-
When future is in an error state, run the provided callback, which can recover from the error and return a new value.
Declaration
Swift
@inlinable public func recover(_ transform: @escaping (Error) throws -> Value) -> CoFuture
Parameters
transform
Function that will receive the error and return a new value or throw an error.
Return Value
A future that will receive the recovered value.
-
When future is fulfilled, run the provided callback, which performs a synchronous computation and return transformed result.
Declaration
Swift
public func mapResult<NewValue>(_ transform: @escaping (Result<Value, Error>) -> Result<NewValue, Error>) -> CoFuture<NewValue>
Parameters
transform
Function that will receive the result and return a new transformed result.
Return Value
A future that will receive the eventual result.
-
When the current
CoFuture
is fulfilled, run the provided callback, which will provide a newCoFuture
.This allows you to dynamically dispatch new asynchronous tasks as phases in a longer series of processing steps. Note that you can use the results of the current
CoFuture
when determining how to dispatch the next operation.Declaration
Swift
@inlinable public func flatMap<NewValue>(_ callback: @escaping (Value) -> CoFuture<NewValue>) -> CoFuture<NewValue>
Parameters
callback
Function that will receive the value and return a new
CoFuture
.Return Value
A future that will receive the eventual value.
-
When the current
CoFuture
is in an error state, run the provided callback, which may recover from the error by returning aCoFuture
.Declaration
Swift
@inlinable public func flatMapError(_ callback: @escaping (Error) -> CoFuture) -> CoFuture
Parameters
callback
Function that will receive the error value and return a new value lifted into a new
CoFuture
.Return Value
A future that will receive the recovered value.
-
When the current
CoFuture
is fulfilled, run the provided callback, which will provide a newCoFuture
.Declaration
Swift
public func flatMapResult<NewValue>(_ callback: @escaping (Result<Value, Error>) -> CoFuture<NewValue>) -> CoFuture<NewValue>
Parameters
callback
Function that will receive the result and return a new
CoFuture
.Return Value
A future that will receive the eventual value.
-
Adds an observer callback that is called when the
CoFuture
has any result.Declaration
Swift
@inlinable public func whenComplete(_ callback: @escaping (Result<Value, Error>) -> Void)
Parameters
callback
The callback that is called when the
CoFuture
is fulfilled. -
Adds an observer callback that is called when the
CoFuture
has a success result.Declaration
Swift
@inlinable public func whenSuccess(_ callback: @escaping (Value) -> Void)
Parameters
callback
The callback that is called with the successful result of the
CoFuture
. -
Adds an observer callback that is called when the
CoFuture
has a failure result.Declaration
Swift
@inlinable public func whenFailure(_ callback: @escaping (Error) -> Void)
Parameters
callback
The callback that is called with the failed result of the
CoFuture
. -
Adds an observer callback that is called when the
CoFuture
is canceled.Declaration
Swift
@inlinable public func whenCanceled(_ callback: @escaping () -> Void)
Parameters
callback
The callback that is called when the
CoFuture
is canceled. -
Adds an observer callback that is called when the
CoFuture
has any result.Declaration
Swift
@inlinable public func whenComplete(_ callback: @escaping () -> Void)
Parameters
callback
The callback that is called when the
CoFuture
is fulfilled.
-
Declaration
Swift
@inlinable public static func == (lhs: CoFuture, rhs: CoFuture) -> Bool
-
Declaration
Swift
@inlinable public func hash(into hasher: inout Hasher)
-
Returns a publisher that emits result of this
CoFuture
.Declaration
Swift
public func publisher() -> AnyPublisher<Value, Error>