https://github.com/bloodyowl/rescript-future
Cancellable futures for ReScript
https://github.com/bloodyowl/rescript-future
Last synced: 10 months ago
JSON representation
Cancellable futures for ReScript
- Host: GitHub
- URL: https://github.com/bloodyowl/rescript-future
- Owner: bloodyowl
- License: mit
- Created: 2020-11-04T17:30:15.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2021-11-05T09:06:34.000Z (about 4 years ago)
- Last Synced: 2025-02-25T15:47:43.201Z (11 months ago)
- Language: ReScript
- Size: 165 KB
- Stars: 68
- Watchers: 6
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: HISTORY.md
- Funding: .github/FUNDING.yml
- License: MIT-LICENSE
Awesome Lists containing this project
- awesome-list - rescript-future
README
# Future
> Cancellable futures for ReScript
## Installation
Run the following in your console:
```console
$ yarn add rescript-future
```
Then add `rescript-future` to your `rescript.json`'s `bs-dependencies`:
```diff
{
"bs-dependencies": [
+ "rescript-future"
]
}
```
## Basics
A **Future** is a data structure that represents a potential value. It works both **synchronously** & **asynchrously**. It consists of **3 possible states**:
- `Pending`: The value is yet to be resolved
- `Cancelled`: The future has been cancelled before could resolve
- `Resolved`: The future holds its value
```reason
// Basic synchronous future
Future.value(1)
->Future.map(x => x + 1)
->Future.flatMap(x => Future.value(x + 1))
->Future.get(Console.log)
// Logs: 3
```
## API
See the details in [the interface file](./src/Future.resi)
### Create
- `value('a) => Future.t<'a>`: creates a resolved future
- `makePure(('a => unit) => unit) => Future.t<'a>`: creates a future
- `make(('a => unit) => option unit>) => Future.t<'a>`: creates a future with a cancellation effect
### Cancel
- `cancel(future)`: Cancels a future and its dependents
### Extract
- `get(future, cb) => unit`: Executes `cb` with `future`'s resolved value
### Transform
- `map(future, mapper)`: Returns a new mapped future
- `flatMap(future, mapper)`: Returns a new mapped future with mapper returning a future itself
### Test
- `isPending(future) => bool`
- `isCancelled(future) => bool`
- `isResolved(future) => bool`
### Result transforms
- `mapResult(future, mapper)`
- `mapOk(future, mapper)`
- `flatMapOk(future, mapper)`
- `mapError(future, mapper)`
- `flatMapError(future, mapper)`
### Debug
- `tap(future, cb) => future`
- `tapOk(resultFuture, cb) => resultFuture`
- `tapError(resultFuture, cb) => resultFuture`
### Multiple futures
- `all2((future, future))`
- `all3((future, future, future))`
- `all4((future, future, future, future))`
- `all5((future, future, future, future, future))`
- `all6((future, future, future, future, future, future))`
- `all(array)`
### Interop
- `FuturePromise.fromPromise`
- `FuturePromise.toPromise`
- `FuturePromise.resultToPromise`
## Cancellation
In JavaScript, `Promises` are not cancellable. That can be limiting at times, especially when using `React`'s `useEffect`, that let's you return a cancellation effect in order to prevent unwanted side-effects.
```reason
let valueFromServer = Future.make(resolve => {
let request = getFromServer((err, data) => {
if err {
resolve(Error(err))
} else {
resolve(Ok(data))
}
})
Some(() => cancelRequest(request))
})
let deserializedValueFromServer =
valueFromServer->Future.map(deserialize)
Future.cancel(valueFromServer)
// valueFromServer & deserializedValueFromServer are cancelled if they were still pending
```
## Aknowledgments
Heavily inspired by [RationalJS/future](https://github.com/RationalJS/future)'s API