Future is a Js.Promise alternative. It is written in ReasonML.
Compared to a promise, a future is:
First make sure you have bs-platform >= 3.1.0. Then install with npm:
$ npm install --save reason-futureThen add "reason-future" to your bsconfig.json dev dependencies:
{
...
"bs-dependencies": [
"reason-future"
]
}To create a task, use Future.make. It provides a single resolve function, like a promise with no reject:
let futureGreeting = Future.make(resolve => resolve("hi"));To get the value of a future, use Future.get:
let futureGreeting = Future.make(resolve => resolve("hi"));
futureGreeting->Future.get(x => Js.log("Got value: " ++ x));
/* Alternatively: */
Future.make(resolve => resolve("hi"))
->Future.get(x => Js.log("Got value: " ++ x));Future.get only retrieves the future value. If you want to transform it to a different value, then you should use Future.map:
/* Shortcut for: let future_A = Future.make(resolve => resolve(99)); */
let future_A = Future.value(99);
let future_B = future_A->Future.map(n => n + 1);
future_A->Future.get(n => Js.log(n)); /* logs: 99 */
future_B->Future.get(n => Js.log(n)); /* logs: 100 */And finally, if you map a future and return another future, you probably want to flatMap instead:
let futureNum = Future.value(50);
let ft_a = futureNum->Future.map(n => Future.value(n + 10));
let ft_b = futureNum->Future.flatMap(n => Future.value(n + 20));
/* ft_a has type future(future(int)) – probably not what you want. */
/* ft_b has type future(int) */Core functions. Note: _ represents the future itself as inserted by -> (the fast pipe operator).
Future.make(resolver) - Create a new, potentially-async future.Future.value(x) - Create a new future with a plain value (synchronous).Future.map(_,fn) - Transform a future value into another valueFuture.flatMap(_,fn) - Transform a future value into another future valueFuture.get(_,fn) - Get the value of a futureFuture.tap(_,fn) - Do something with the value of a future without changing it. Returns the same future so you can continue using it in a pipeline. Convenient for side effects such as console logging.Future.all(_,fn) - Turn a list of futures into a future of a list. Used when you want to wait for a collection of futures to complete before doing something (equivalent to Promise.all in Javascript).Convenience functions when working with a future Belt.Result. Note: _ represents the future itself as inserted by -> (the fast pipe operator).
Note 2: The terms Result.Ok and Result.Error in this context are expected to be read as Belt.Result.Ok and Belt.Result.Error.
Future.mapOk(_,fn) - Transform a future value into another value, but only if the value is an Result.Ok. Similar to Promise.prototype.thenFuture.mapError(_,fn) - Transform a future value into another value, but only if the value is an Result.Error. Similar to Promise.prototype.catchFuture.tapOk(_,fn) - Do something with the value of a future without changing it, but only if the value is a Belt.Result.Ok. Returns the same future. Convenience for side effects such as console logging.Future.tapError(_,fn) - Same as tapOk but for Result.ErrorThe following are more situational:
Future.flatMapOk(_, fn) - Transform a future Result.Ok into
a future Result. Flattens the inner future.Future.flatMapError(_, fn) - Transform a future Result.Error into
a future Result. Flattens the inner future.Convenience functions for interop with JavaScript land.
FutureJs.fromPromise(promise, errorTransformer)
promise is the Js.Promise.t('a) that will be transformed into a
Future.t(Belt.Result.t('a, 'e))errorTransformer allows you to determine how Js.Promise.error
objects will be transformed before they are returned wrapped within
a Belt.Result.Error. This allows you to implement the error handling
method which best meets your application's needs.FutureJs.toPromise(future)
future is any Future.t('a) which is transformed into a
Js.Promise.t('a). Always resolves, never rejects the promise.FutureJs.resultToPromise(future)
future is the Future.t(Belt.Result('a, 'e)) which is transformed into a
Js.Promise.t('a). Resolves the promise on Ok result and rejects on Error result.Example use:
/*
This error handler is super simple; you will probably want
to write something more sophisticated in your app.
*/
let handleError = Js.String.make;
somePromiseGetter()
->FutureJs.fromPromise(handleError)
->Future.tap(value => Js.log2("It worked!", value))
->Future.tapError(err => Js.log2("uh on", err));See Composible Error Handling in OCaml for several strategies that you may employ.
By default this library is not stack safe, you will recieve a 'Maximum call stack size exceeded' error if you recurse too deeply. You can opt into stack safety by passing an optional parameter to the constructors of trampoline. This has a slight overhead. For example:
let stackSafe = Future.make(~executor=`trampoline, resolver);
let stackSafeValue = Future.value(~executor=`trampoline, "Value");
let stackSafe = Future.make ~executor:`trampoline resolver
let stackSafeValue = Future.value ~executor:`trampoline "Value"
Js.PromiseflatMapOk / flatMapError (with composable error handling)npm run buildnpm run startnpm testIf you use vscode, Press Windows + Shift + B it will build automatically