Skip to content

Commit c4b6902

Browse files
committed
Add more bindings to Promise utils
1 parent 6d2d3d8 commit c4b6902

File tree

2 files changed

+215
-4
lines changed

2 files changed

+215
-4
lines changed

src/Core__Promise.res

+64-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,16 @@ type t<+'a> = promise<'a>
33
@new
44
external make: (('a => unit, 'e => unit) => unit) => t<'a> = "Promise"
55

6-
@val @scope("Promise")
6+
type resolvers<'a> = {
7+
promise: t<'a>,
8+
resolve: 'a => unit,
9+
reject: exn => unit,
10+
}
11+
12+
@scope("Promise") @val
13+
external withResolvers: unit => resolvers<_> = "withResolvers"
14+
15+
@scope("Promise") @val
716
external resolve: 'a => t<'a> = "resolve"
817

918
@send external then: (t<'a>, 'a => t<'b>) => t<'b> = "then"
@@ -34,6 +43,57 @@ external all5: ((t<'a>, t<'b>, t<'c>, t<'d>, t<'e>)) => t<('a, 'b, 'c, 'd, 'e)>
3443
@scope("Promise") @val
3544
external all6: ((t<'a>, t<'b>, t<'c>, t<'d>, t<'e>, t<'f>)) => t<('a, 'b, 'c, 'd, 'e, 'f)> = "all"
3645

46+
@tag("status")
47+
type settledResult<+'a> =
48+
| @as("fulfilled") Fulfilled({value: 'a}) | @as("rejected") Rejected({reason: exn})
49+
50+
@scope("Promise") @val
51+
external allSettled: array<promise<'a>> => promise<array<settledResult<'a>>> = "allSettled"
52+
53+
@scope("Promise") @val
54+
external allSettled2: ((promise<'a0>, promise<'a1>)) => promise<(
55+
settledResult<'a0>,
56+
settledResult<'a1>,
57+
)> = "allSettled"
58+
59+
@scope("Promise") @val
60+
external allSettled3: ((promise<'a0>, promise<'a1>, promise<'a2>)) => promise<(
61+
settledResult<'a0>,
62+
settledResult<'a1>,
63+
settledResult<'a2>,
64+
)> = "allSettled"
65+
66+
@scope("Promise") @val
67+
external allSettled4: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>)) => promise<(
68+
settledResult<'a0>,
69+
settledResult<'a1>,
70+
settledResult<'a2>,
71+
settledResult<'a3>,
72+
)> = "allSettled"
73+
74+
@scope("Promise") @val
75+
external allSettled5: (
76+
(promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>)
77+
) => promise<(
78+
settledResult<'a0>,
79+
settledResult<'a1>,
80+
settledResult<'a2>,
81+
settledResult<'a3>,
82+
settledResult<'a4>,
83+
)> = "allSettled"
84+
85+
@scope("Promise") @val
86+
external allSettled6: (
87+
(promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>, promise<'a5>)
88+
) => promise<(
89+
settledResult<'a0>,
90+
settledResult<'a1>,
91+
settledResult<'a2>,
92+
settledResult<'a3>,
93+
settledResult<'a4>,
94+
settledResult<'a5>,
95+
)> = "allSettled"
96+
3797
@send
3898
external _catch: (t<'a>, exn => t<'a>) => t<'a> = "catch"
3999

@@ -46,4 +106,7 @@ let catch = (promise: promise<'a>, callback: exn => promise<'a>): promise<'a> =>
46106
@scope("Promise") @val
47107
external race: array<t<'a>> => t<'a> = "race"
48108

109+
@scope("Promise") @val
110+
external any: array<t<'a>> => t<'a> = "any"
111+
49112
external done: promise<'a> => unit = "%ignore"

src/Core__Promise.resi

+151-3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,37 @@ Promise.make((resolve, reject) => {
7575
@new
7676
external make: (('a => unit, 'e => unit) => unit) => t<'a> = "Promise"
7777

78+
type resolvers<'a> = {
79+
promise: t<'a>,
80+
resolve: 'a => unit,
81+
reject: exn => unit,
82+
}
83+
84+
/**
85+
`withResolvers()` returns a object containing a new promise with functions to resolve or reject it. See [`Promise.withResolvers`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers) on MDN.
86+
87+
## Examples
88+
89+
```rescript
90+
open Promise
91+
92+
let {promise, resolve, _} = Promise.withResolvers()
93+
94+
setTimeout(() => {
95+
resolve(. "success")
96+
}, 1000)->ignore
97+
98+
promise
99+
->then(str => {
100+
Console.log(str)->resolve
101+
})
102+
->ignore
103+
```
104+
*/
105+
@scope("Promise")
106+
@val
107+
external withResolvers: unit => resolvers<_> = "withResolvers"
108+
78109
/**
79110
`catch(promise, errorCallback)` registers an exception handler in a promise chain.
80111
The `errorCallback` receives an `exn` value that can later be refined into a JS
@@ -206,7 +237,7 @@ resolve(5)
206237
external finally: (t<'a>, unit => unit) => t<'a> = "finally"
207238

208239
/**
209-
`race(arr)` combining `array` of promises. See [`Promise.race`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race) on MDN.
240+
`race(arr)` runs all promises concurrently and returns promise settles with the eventual state of the first promise that settles. See [`Promise.race`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race) on MDN.
210241

211242
## Examples
212243

@@ -233,8 +264,34 @@ race(promises)->then(winner => {
233264
external race: array<t<'a>> => t<'a> = "race"
234265

235266
/**
236-
`all(promises)` runs all promises in parallel and returns a new promise resolving
237-
all gathered results in a unified array. See [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) on MDN.
267+
`any(arr)` runs all promises concurrently and returns promise fulfills when any of the input's promises fulfills, with this first fulfillment value. See [`Promise.any`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any) on MDN.
268+
269+
## Examples
270+
271+
```rescript
272+
open Promise
273+
let racer = (ms, name) => {
274+
Promise.make((resolve, _) => {
275+
setTimeout(() => {
276+
resolve(name)
277+
}, ms)->ignore
278+
})
279+
}
280+
281+
let promises = [racer(1000, "Turtle"), racer(500, "Hare"), racer(100, "Eagle")]
282+
283+
any(promises)->then(winner => {
284+
Console.log("The winner is " ++ winner)
285+
resolve()
286+
})
287+
```
288+
*/
289+
@scope("Promise")
290+
@val
291+
external any: array<t<'a>> => t<'a> = "any"
292+
293+
/**
294+
`all(promises)` runs all promises concurrently and returns a promise fulfills when all of the input's promises fulfill, with an array of the fulfillment values. See [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) on MDN.
238295

239296
```rescript
240297
open Promise
@@ -290,6 +347,97 @@ external all5: ((t<'a>, t<'b>, t<'c>, t<'d>, t<'e>)) => t<('a, 'b, 'c, 'd, 'e)>
290347
@val
291348
external all6: ((t<'a>, t<'b>, t<'c>, t<'d>, t<'e>, t<'f>)) => t<('a, 'b, 'c, 'd, 'e, 'f)> = "all"
292349

350+
@tag("status")
351+
type settledResult<+'a> =
352+
| @as("fulfilled") Fulfilled({value: 'a}) | @as("rejected") Rejected({reason: exn})
353+
354+
/**
355+
`allSettled(promises)` runs all promises concurrently and returns promise fulfills when all of the input's promises settle with an array of objects that describe the outcome of each promise. See [`Promise.allSettled`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled) on MDN.
356+
357+
```rescript
358+
open Promise
359+
360+
exception TestError(string)
361+
362+
let promises = [resolve(1), resolve(2), reject(TestError("some rejected promise"))]
363+
364+
allSettled(promises)
365+
->then((results) => {
366+
results->Array.forEach((result) => {
367+
switch result {
368+
| Fulfilled({value: num}) =>
369+
Console.log2("Number: ", num)
370+
| Rejected({reason}) =>
371+
Console.log(reason)
372+
}
373+
})
374+
375+
resolve()
376+
})
377+
->ignore
378+
```
379+
*/
380+
@scope("Promise")
381+
@val
382+
external allSettled: array<t<'a>> => t<array<settledResult<'a>>> = "allSettled"
383+
384+
/**
385+
`allSettled2((p1, p2))`. Like `allSettled()`, but with a fixed size tuple of 2
386+
*/
387+
@scope("Promise")
388+
@val
389+
external allSettled2: ((t<'a>, t<'b>)) => t<(settledResult<'a>, settledResult<'b>)> = "allSettled"
390+
391+
/**
392+
`allSettled3((p1, p2, p3))`. Like `allSettled()`, but with a fixed size tuple of 3
393+
*/
394+
@scope("Promise")
395+
@val
396+
external allSettled3: ((t<'a>, t<'b>, t<'c>)) => t<(
397+
settledResult<'a>,
398+
settledResult<'b>,
399+
settledResult<'c>,
400+
)> = "allSettled"
401+
402+
/**
403+
`allSettled4((p1, p2, p3, p4))`. Like `allSettled()`, but with a fixed size tuple of 4
404+
*/
405+
@scope("Promise")
406+
@val
407+
external allSettled4: ((t<'a>, t<'b>, t<'c>, t<'d>)) => t<(
408+
settledResult<'a>,
409+
settledResult<'b>,
410+
settledResult<'c>,
411+
settledResult<'d>,
412+
)> = "allSettled"
413+
414+
/**
415+
`allSettled5((p1, p2, p3, p4, p5))`. Like `allSettled()`, but with a fixed size tuple of 5
416+
*/
417+
@scope("Promise")
418+
@val
419+
external allSettled5: ((t<'a>, t<'b>, t<'c>, t<'d>, t<'e>)) => t<(
420+
settledResult<'a>,
421+
settledResult<'b>,
422+
settledResult<'c>,
423+
settledResult<'d>,
424+
settledResult<'e>,
425+
)> = "allSettled"
426+
427+
/**
428+
`allSettled6((p1, p2, p4, p5, p6))`. Like `allSettled()`, but with a fixed size tuple of 6
429+
")*/
430+
@scope("Promise")
431+
@val
432+
external allSettled6: ((t<'a>, t<'b>, t<'c>, t<'d>, t<'e>, t<'f>)) => t<(
433+
settledResult<'a>,
434+
settledResult<'b>,
435+
settledResult<'c>,
436+
settledResult<'d>,
437+
settledResult<'e>,
438+
settledResult<'f>,
439+
)> = "allSettled"
440+
293441
/**
294442
`done(p)` is a safe way to ignore a promise. If a value is anything else than a
295443
promise, it will raise a type error.

0 commit comments

Comments
 (0)