Classes
The following classes are available globally.
-
Channel is a non-blocking primitive for communication between a sender and a receiver. Conceptually, a channel is similar to a queue that allows to suspend a coroutine on receive if it is empty or on send if it is full.
Important
Alwaysclose()
orcancel()
a channel when you are done to resume all suspended coroutines by the channel.
See morelet channel = CoChannel<Int>(capacity: 1) DispatchQueue.global().startCoroutine { for i in 0..<100 { try channel.awaitSend(i) } channel.close() } DispatchQueue.global().startCoroutine { for i in channel.makeIterator() { print("Receive", i) } print("Done") }
Declaration
-
Holder for a result that will be provided later.
CoFuture
and its subclassCoPromise
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 thewhenComplete()
callback or byawait()
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 useCoFuture
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 makingCoFuture
a subscriber and await its result.
See more//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() }
Declaration
-
The holder of uncompleted
CoCancellable
and coroutines.CoScope
helps to manage lifecycle of coroutines andCoCancellable
, likeCoFuture
andCoChannel
. It keeps weak references on inner objects and cancels them oncancel()
or deinit. All completed objects are automaticaly removed from scope.Note
CoScope
keeps weak references.
See morelet scope = CoScope() let future = makeSomeFuture().added(to: scope) queue.startCoroutine(in: scope) { . . . some code . . . let result = try future.await() . . . some code . . . } let future2 = queue.coroutineFuture { try Coroutine.delay(.seconds(5)) // imitate some work return 5 }.added(to: scope) //cancel all added futures and coroutines scope.cancel()
Declaration