API / Core / Promise

Promise

Functions for interacting with JavaScript Promise. See: Promise.

t

RESCRIPT
type t<'a> = promise<'a>

resolve

RESCRIPT
let resolve: 'a => t<'a>

resolve(value) creates a resolved Promise with a given value. See Promise.resolve on MDN.

Examples

RESCRIPT
let p = Promise.resolve(5) // promise<int>

reject

RESCRIPT
let reject: exn => t<'a>

reject(exn) reject a Promise. See Promise.reject on MDN.

Examples

RESCRIPT
exception TestError(string) let p = Promise.reject(TestError("some rejected value"))

make

RESCRIPT
let make: (('a => unit, 'e => unit) => unit) => t<'a>

make(callback) creates a new Promise based on a callback that receives two uncurried functions resolve and reject for defining the Promise's result.

Examples

RESCRIPT
open Promise let n = 4 Promise.make((resolve, reject) => { if(n < 5) { resolve(. "success") } else { reject(. "failed") } }) ->then(str => { Console.log(str)->resolve }) ->catch(_ => { Console.log("Error occurred") resolve() }) ->ignore

promiseAndResolvers

RESCRIPT
type promiseAndResolvers<'a> = { promise: t<'a>, resolve: 'a => unit, reject: exn => unit, }

withResolvers

RESCRIPT
let withResolvers: unit => promiseAndResolvers<'a>

withResolvers() returns a object containing a new promise with functions to resolve or reject it. See Promise.withResolvers on MDN.

Examples

RESCRIPT
open Promise let {promise, resolve, _} = Promise.withResolvers() setTimeout(() => { resolve(. "success") }, 1000)->ignore promise ->thenResolve(str => { Console.log(str) }) ->ignore

catch

RESCRIPT
let catch: (t<'a>, exn => t<'a>) => t<'a>

catch(promise, errorCallback) registers an exception handler in a promise chain. The errorCallback receives an exn value that can later be refined into a JS error or ReScript error. The errorCallback needs to return a promise with the same type as the consumed promise. See Promise.catch on MDN.

Examples

RESCRIPT
open Promise exception SomeError(string) reject(SomeError("this is an error")) ->then(_ => { Ok("This result will never be returned")->resolve }) ->catch(e => { let msg = switch(e) { | SomeError(msg) => "ReScript error occurred: " ++ msg | Exn.Error(obj) => switch Exn.message(obj) { | Some(msg) => "JS exception occurred: " ++ msg | None => "Some other JS value has been thrown" } | _ => "Unexpected error occurred" } Error(msg)->resolve }) ->then(result => { switch result { | Ok(r) => Console.log2("Operation successful: ", r) | Error(msg) => Console.log2("Operation failed: ", msg) }->resolve }) ->ignore // Ignore needed for side-effects

In case you want to return another promise in your callback, consider using then instead.

then

RESCRIPT
let then: (t<'a>, 'a => t<'b>) => t<'b>

then(promise, callback) returns a new promise based on the result of promise's value. The callback needs to explicitly return a new promise via resolve. It is not allowed to resolve a nested promise (like resolve(resolve(1))). See Promise.then on MDN.

Examples

RESCRIPT
open Promise resolve(5) ->then(num => { resolve(num + 5) }) ->then(num => { Console.log2("Your lucky number is: ", num) resolve() }) ->ignore

thenResolve

RESCRIPT
let thenResolve: (t<'a>, 'a => 'b) => t<'b>

thenResolve(promise, callback) converts an encapsulated value of a promise into another promise wrapped value. It is not allowed to return a promise within the provided callback (e.g. thenResolve(value => resolve(value))).

Examples

RESCRIPT
open Promise resolve("Anna") ->thenResolve(str => { "Hello " ++ str }) ->thenResolve(str => { Console.log(str) }) ->ignore // Ignore needed for side-effects

In case you want to return another promise in your callback, consider using then instead.

finally

RESCRIPT
let finally: (t<'a>, unit => unit) => t<'a>

finally(promise, callback) is used to execute a function that is called no matter if a promise was resolved or rejected. It will return the same promise it originally received. See Promise.finally on MDN.

Examples

RESCRIPT
open Promise exception SomeError(string) let isDone = ref(false) resolve(5) ->then(_ => { reject(SomeError("test")) }) ->then(v => { Console.log2("final result", v) resolve() }) ->catch(_ => { Console.log("Error handled") resolve() }) ->finally(() => { Console.log("finally") isDone := true }) ->then(() => { Console.log2("isDone:", isDone.contents) resolve() }) ->ignore

race

RESCRIPT
let race: array<t<'a>> => t<'a>

race(arr) runs all promises concurrently and returns promise settles with the eventual state of the first promise that settles. See Promise.race on MDN.

Examples

RESCRIPT
open Promise let racer = (ms, name) => { Promise.make((resolve, _) => { setTimeout(() => { resolve(name) }, ms)->ignore }) } let promises = [racer(1000, "Turtle"), racer(500, "Hare"), racer(100, "Eagle")] race(promises)->then(winner => { Console.log("The winner is " ++ winner) resolve() })

any

RESCRIPT
let any: array<t<'a>> => t<'a>

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 on MDN.

Examples

RESCRIPT
open Promise let racer = (ms, name) => { Promise.make((resolve, _) => { setTimeout(() => { resolve(name) }, ms)->ignore }) } let promises = [racer(1000, "Turtle"), racer(500, "Hare"), racer(100, "Eagle")] any(promises)->then(winner => { Console.log("The winner is " ++ winner) resolve() })

all

RESCRIPT
let all: array<t<'a>> => t<array<'a>>

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 on MDN.

RESCRIPT
open Promise let promises = [resolve(1), resolve(2), resolve(3)] all(promises) ->then((results) => { results->Array.forEach(num => { Console.log2("Number: ", num) }) resolve() }) ->ignore

all2

RESCRIPT
let all2: ((t<'a>, t<'b>)) => t<('a, 'b)>

all2((p1, p2)). Like all(), but with a fixed size tuple of 2

all3

RESCRIPT
let all3: ((t<'a>, t<'b>, t<'c>)) => t<('a, 'b, 'c)>

all3((p1, p2, p3)). Like all(), but with a fixed size tuple of 3

all4

RESCRIPT
let all4: ((t<'a>, t<'b>, t<'c>, t<'d>)) => t<('a, 'b, 'c, 'd)>

all4((p1, p2, p3, p4)). Like all(), but with a fixed size tuple of 4

all5

RESCRIPT
let all5: ( (t<'a>, t<'b>, t<'c>, t<'d>, t<'e>), ) => t<('a, 'b, 'c, 'd, 'e)>

all5((p1, p2, p3, p4, p5)). Like all(), but with a fixed size tuple of 5

all6

RESCRIPT
let all6: ( (t<'a>, t<'b>, t<'c>, t<'d>, t<'e>, t<'f>), ) => t<('a, 'b, 'c, 'd, 'e, 'f)>

all6((p1, p2, p4, p5, p6)). Like all(), but with a fixed size tuple of 6 ")

settledResult

RESCRIPT
type settledResult<'a> = | Fulfilled({value: 'a}) | Rejected({reason: exn})

allSettled

RESCRIPT
let allSettled: array<t<'a>> => t<array<settledResult<'a>>>

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 on MDN.

RESCRIPT
open Promise exception TestError(string) let promises = [resolve(1), resolve(2), reject(TestError("some rejected promise"))] allSettled(promises) ->then((results) => { results->Array.forEach((result) => { switch result { | Fulfilled({value: num}) => Console.log2("Number: ", num) | Rejected({reason}) => Console.log(reason) } }) resolve() }) ->ignore

allSettled2

RESCRIPT
let allSettled2: ( (t<'a>, t<'b>), ) => t<(settledResult<'a>, settledResult<'b>)>

allSettled2((p1, p2)). Like allSettled(), but with a fixed size tuple of 2

allSettled3

RESCRIPT
let allSettled3: ( (t<'a>, t<'b>, t<'c>), ) => t< (settledResult<'a>, settledResult<'b>, settledResult<'c>), >

allSettled3((p1, p2, p3)). Like allSettled(), but with a fixed size tuple of 3

allSettled4

RESCRIPT
let allSettled4: ( (t<'a>, t<'b>, t<'c>, t<'d>), ) => t< ( settledResult<'a>, settledResult<'b>, settledResult<'c>, settledResult<'d>, ), >

allSettled4((p1, p2, p3, p4)). Like allSettled(), but with a fixed size tuple of 4

allSettled5

RESCRIPT
let allSettled5: ( (t<'a>, t<'b>, t<'c>, t<'d>, t<'e>), ) => t< ( settledResult<'a>, settledResult<'b>, settledResult<'c>, settledResult<'d>, settledResult<'e>, ), >

allSettled5((p1, p2, p3, p4, p5)). Like allSettled(), but with a fixed size tuple of 5

allSettled6

RESCRIPT
let allSettled6: ( (t<'a>, t<'b>, t<'c>, t<'d>, t<'e>, t<'f>), ) => t< ( settledResult<'a>, settledResult<'b>, settledResult<'c>, settledResult<'d>, settledResult<'e>, settledResult<'f>, ), >

allSettled6((p1, p2, p4, p5, p6)). Like allSettled(), but with a fixed size tuple of 6 ")

done

RESCRIPT
let done: promise<'a> => unit

done(p) is a safe way to ignore a promise. If a value is anything else than a promise, it will raise a type error.