Classes
The following classes are available globally.
-
Holder for a result that will be provided later.
CoFuture
and it’s subclassCoPromise
є імплементацією Future/Promise підходу. Це дозволяє виконувати асинхронно роботу immediately повернувшиCoFuture
, яке can be observed to be notified when result will be available. For example:extension URLSession { typealias DataResponse = (data: Data, response: URLResponse) func dataTaskFuture(for urlRequest: URLRequest) -> CoFuture<DataResponse> { let promise = CoPromise<DataResponse>() let task = dataTask(with: urlRequest) { if let error = $2 { promise.fail(error) } else if let data = $0, let response = $1 { promise.success((data, response)) } else { promise.fail(URLError(.badServerResponse)) } } task.resume() //cancel task if future will cancel promise.whenCanceled(task.cancel) return promise } }
За допомогою
whenComplete()
ви можете додати callback або використатиawait()
в середині коротини для отримання результату.CoFuture
є повністю thread-safe.Features
Best performance
Основною ціллю при створенні
CoFuture
було досягнення найкращої швидкодії. Було витрачено багато часу і перебрано багато варіантів для цього(для того щоб знайти найкращий). Як результатCoFuture
є швидшим ніж аналогічні рішення:- CoFuture - 0.083 c.
- Combine Future - 0.234 c. (2.8x slower)
- Найпопулярніша Swift Future/Promise library on GitHub - 0.521 c. (6.3x slower)
Тести для
CoFuture
та CombineFuture
ви можете знайти в файліCoFuturePerformanceTests
. Тест проводився на MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports) у release mode.Build chains
За допомогою
flatMap()
ви можете створювати chain ofCoFuture
, that allows you to do more asynchronous processing. Або ви можете використатиmap()
для синхронного трансформування. В кінці ви можете використатиwhenSuccess()
orwhenFailure()
для observing callback with the result or error.//some future that will return URLRequest let requestFuture: CoFuture<URLRequest> requestFuture.flatMap { request in URLSession.shared.dataTaskFuture(for: request) }.flatMap { data, response in CoFuture(on: .global) { //do some work on global queue that return some result } }.map { transformData($0) }.whenComplete { result in //result handler }
Cancellable
За допомогою
cancel()
ви можете завершити весь upstream chain of CoFutures. Також ви можете handle cancelling і завершити пов’язані таски.let future = URLSession.shared.dataTaskFuture(for: request) future.whenCanceled { //handle when canceled } //will also cancel URLSessionDataTask future.cancel()
Awaitable
Ви можете використовувати
await()
всерединіCoroutine
для реалізації async/await патерну для отримання результату. Вона дозволяє працювати з асинхронним кодом в синхронній манері без блокування потоку.//execute coroutine on main thread CoroutineDispatcher.main.execute { //extension that returns CoFuture<URLSession.DataResponse> let future = URLSession.shared.dataTaskFuture(for: request) //await result that suspends coroutine and doesn't block the thread let data = try future.await().data //set the image on main thread self.imageView.image = UIImage(data: data) }
Combine ready
CoFuture
легко інтегрується з Combine, так за допомогоюpublisher()
ви можете створитиPublisher
, який transmit результат як тільки він буде готовий. Крім цього доPublisher
був доданий extensionsubscribeCoFuture()
, який дає можливість subscribeCoFuture
, який отримає лише один результат. Ви можете використовуватиawait()
для цьогоCoFuture
, щоб отримати результат дляPublisher
всередині коротини.
See moreCoroutineDispatcher.main.execute { //returns Publishers.MapKeyPath<URLSession.DataTaskPublisher, Data> let publisher = URLSession.shared.dataTaskPublisher(for: request).map(\.data) //await data without blocking the thread let data = try publisher.await() //do some work with data }
Declaration
Swift
public class CoFuture<Value>
extension CoFuture: Hashable
extension CoFuture: Cancellable
-
A promise to provide a result later.
See moreCoPromise
is subclass ofCoFuture
, що має методи, які дозволяють fulfill it. Це дозволяє інкапсулювати result provider. Ви можете тільки один раз засетати результат вCoPromise
, всі інші рази будуть ігноруватись.Declaration
Swift
public final class CoPromise<Value> : CoFuture<Value>