diff --git a/README.md b/README.md index 0478d65..f4c00fc 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Core functions. **Note:** `_` represents the future itself as inserted by `->` ( - `Future.flatMap(_,fn)` - Transform a future value into another future value - `Future.get(_,fn)` - Get the value of a future - `Future.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). ### Belt.Result diff --git a/src/Future.re b/src/Future.re index 4aa91cf..50399cc 100644 --- a/src/Future.re +++ b/src/Future.re @@ -49,6 +49,16 @@ let map4 = (fa, fb, fc, fd, f) => map3(map2(fa, fb, f), fc, fd, v => v); let map5 = (fa, fb, fc, fd, fe, f) => map4(map2(fa, fb, f), fc, fd, fe, v => v); +let rec all = futures => + switch (futures) { + | [head, ...tail] => + all(tail) + ->flatMap(tailResult => + head->map(headResult => [headResult, ...tailResult]) + ) + | [] => value([]) + }; + let tap = (Future(get) as future, f) => { get(f); future; diff --git a/tests/TestFuture.re b/tests/TestFuture.re index 9ddffe1..17e6935 100644 --- a/tests/TestFuture.re +++ b/tests/TestFuture.re @@ -103,6 +103,16 @@ describe("Future", () => { future->Future.get(_ => done_()); }); + + testAsync("all (async)", done_ => + Future.all([Future.value(1), delay(25, () => 2), delay(50, () => 3)]) + ->Future.get(result => + switch (result) { + | [1, 2, 3] => done_() + | _ => raise(TestError("Expected [1, 2, 3]")) + } + ) + ); }); describe("Future Belt.Result", () => {