Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/davidask/futures
Lightweight promises for iOS, macOS, tvOS, watchOS, and Linux
https://github.com/davidask/futures
async futures ios macos promises server-side-swift swift tvos watchos
Last synced: 6 days ago
JSON representation
Lightweight promises for iOS, macOS, tvOS, watchOS, and Linux
- Host: GitHub
- URL: https://github.com/davidask/futures
- Owner: davidask
- License: mit
- Created: 2018-05-25T20:08:36.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2020-06-11T20:38:02.000Z (over 4 years ago)
- Last Synced: 2024-08-04T11:02:02.504Z (3 months ago)
- Topics: async, futures, ios, macos, promises, server-side-swift, swift, tvos, watchos
- Language: Swift
- Homepage:
- Size: 1.65 MB
- Stars: 57
- Watchers: 3
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Futures
![Tests](https://github.com/davidask/Futures/workflows/Tests/badge.svg)Futures is a cross-platform framework for simplifying asynchronous programming, written in Swift. It's lightweight, fast, and easy to understand.
### Supported Platforms
* Ubuntu 14.04
* macOS 10.9
* tvOS 9.0
* iOS 8.0
* watchOS 2.0### Architecture
Fundamentally, Futures is a very simple framework, that consists of two types:
* `Promise`, a single assignment container producing a `Future`
* `Future`, a read-only container resolving into either a value, or an errorIn many promise frameworks, a promise is undistinguished from a future. This introduces mutability of a promise that gets passed around. In Futures, a `Future` is the observable value while a `Promise` is the function that sets the value.
Futures are observed, by default, on a single concurrent dispatch queue. This queue can be modified by assigning a different queue to `DispatchQueue.futures`. You can also specify a queue of your choice to each callback added to a future .
A future is regarded as:
* `resolved`, if its value is set
* `fulfilled`, if the value is set, and successful
* `rejected`, if the value is set, and a failure (error)## Usage
When a function returns a `Future`, you can either decide to observe it directly, or continue with more asynchronous tasks. For observing, you use:
* `whenResolved`, if you're interested in both a value and a rejection error
* `whenFulfilled`, if you only care about the values
* `whenRejected`, if you only care about the errorIf you have more asynchronous work to do based on the result of the first future, you can use
* `flatMap()`, to execute another future based on the result of the current one
* `flatMapIfRejected()`, to recover from a potential error resulting from the current future
* `flatMapThrowing()`, to transform the fulfilled value of the current future or return a rejected future
* `map()`, to transform the fulfilled value of the current future
* `recover()`,to transform a rejected future into a fulfilled future
* `always()`, to execute a `Void` returning closure regardless of whether the current future is rejected or resolved
* `and()`, to combine the result of two futures into a single tuple
* `Future.reduce()`, to combine the result of multiple futures into a single futureNote that you can specify an observation dispatch queue for all these functions. For instance, you can use `flatMap(on: .main)`, or `.map(on: .global())`. By default, the queue is `DispatchQueue.futures`.
As a simple example, this is how some code may look:
```swift
let future = loadNetworkResource(
from: URL("http://someHost/resource")!
).flatMapThrowing { data in
try jsonDecoder.decode(SomeType.self, from: data)
}.always {
someFunctionToExecuteRegardless()
}future.whenFulfilled(on: .main) { someType in
// Success
}future.whenRejected(on: .main) { error in
// Error
}
```To create your functions returning a `Future`, you create a new pending promise, and resolve it when appropriate.
```swift
func performAsynchronousWork() -> Future {
let promise = Promise()DispatchQueue.global().async {
promise.fulfill(someString)// If error
promise.reject(error)
}return promise.future
}
```You can also use shorthands.
```swift
promise {
try jsonDecoder.decode(SomeType.self, from: data)
} // Future
```Or shorthands which you can return from asynchronously.
```swift
promise(String.self) { completion in
/// ... on success ...
completion(.fulfill("Some string"))
/// ... if error ...
completion(.reject(anError))
} // Future
```## Documentation
The complete documentation can be found [here](https://davidask.github.io/Futures/).
## Getting started
Futures can be added to your project either using [Carthage](https://github.com/Carthage/Carthage) or Swift package manager.
If you want to depend on Futures in your project, it's as simple as adding a `dependencies` clause to your `Package.swift`:
```swift
dependencies: [
.package(url: "https://github.com/davidask/Futures.git", from: "1.6.0")
]
```Or, add a dependency in your `Cartfile`:
```
github "davidask/Futures"
```More details on using Carthage can be found [here](https://github.com/Carthage/Carthage#quick-start).
Lastly, import the module in your Swift files
```swift
import Futures
```## Contribute
Please feel welcome contributing to **Futures**, check the ``LICENSE`` file for more info.## Credits
David Ask