This is the latest docs version
Quick Links
  • -Overview
  • -Language Features
  • -JS Interop
  • -Build System
Documentation
Language Manual
Reference for all language features
ReScript & React
First class bindings for ReactJS
GenType
Seamless TypeScript integration
Reanalyze
Dead Code & Termination analysis
Exploration
Packages
Explore third party libraries and bindings
Syntax Lookup
Discover all syntax constructs
APIPlaygroundBlogCommunity
  • Playground
  • Blog
  • Twitter
  • GitHub
  • Forum
Language Manual
Overview
  • Introduction
  • Installation
  • Migrate to v11
  • Editor Plugins
  • Try
Language Features
  • Overview
  • Let Binding
  • Type
  • Primitive Types
  • Tuple
  • Record
  • Object
  • Variant
  • Polymorphic Variant
  • Null, Undefined and Option
  • Array & List
  • Function
  • If-Else & Loops
  • Pipe
  • Pattern Matching / Destructuring
  • Mutation
  • JSX
  • Exception
  • Lazy Value
  • Promises
    • promise type
    • Promise
    • Js.Promise module (legacy - do not use)
  • Async / Await
  • Tagged templates
  • Module
  • Import & Export
  • Attribute (Decorator)
  • Reserved Keywords
  • Equality and Comparison
Advanced Features
  • Extensible Variant
  • Scoped Polymorphic Types
JavaScript Interop
  • Interop Cheatsheet
  • Embed Raw JavaScript
  • Shared Data Types
  • External (Bind to Any JS Library)
  • Bind to JS Object
  • Bind to JS Function
  • Import from / Export to JS
  • Bind to Global JS Values
  • JSON
  • Inlining Constants
  • Use Illegal Identifier Names
  • Generate Converters & Helpers
  • Browser Support & Polyfills
  • Libraries & Publishing
  • TypeScript
Build System
  • Overview
  • Configuration
  • Configuration Schema
  • External Stdlib
  • Pinned Dependencies
  • Interop with JS Build Systems
  • Performance
  • Warning Numbers
Guides
  • Converting from JS
Extra
  • Newcomer Examples
  • Project Structure
  • FAQ
Docs / Language Manual / Promises
Edit

Promise

Note: Starting from ReScript 10.1 and above, we recommend using async / await when interacting with Promises.

promise type

Since 10.1

In ReScript, every JS promise is represented with the globally available promise<'a> type. For ReScript versions < 10.1, use its original alias Js.Promise.t<'a> instead.

Here's a usage example in a function signature:

RESI
// User.resi file type user = {name: string} let fetchUser: string => promise<user>

To work with promise values (instead of using async / await) you may want to use the built-in Promise module.

Promise

A builtin module to create, chain and manipulate promises.

Creating a promise

RES
let p1 = Promise.make((resolve, reject) => { // We use uncurried functions for resolve / reject // for cleaner JS output without unintended curry calls resolve("hello world") }) let p2 = Promise.resolve("some value") // You can only reject `exn` values for streamlined catch handling exception MyOwnError(string) let p3 = Promise.reject(MyOwnError("some rejection"))

Access the contents and transform a promise

RES
let logAsyncMessage = () => { open Promise Promise.resolve("hello world") ->then(msg => { // then callbacks require the result to be resolved explicitly resolve("Message: " ++ msg) }) ->then(msg => { Console.log(msg) // Even if there is no result, we need to use resolve() to return a promise resolve() }) ->ignore // Requires ignoring due to unhandled return value }

For comparison, the async / await version of the same code would look like this:

RES
let logAsyncMessage = async () => { let msg = await Promise.resolve("hello world") Console.log(`Message: ${msg}`) }

Needless to say, the async / await version offers better ergonomics and less opportunities to run into type issues.

Run multiple promises in parallel

In case you want to launch multiple promises in parallel, use Promise.all:

ReScriptJS Output
@val
external fetchMessage: string => promise<string> = "global.fetchMessage"

let logAsyncMessage = async () => {
  let messages = await Promise.all([fetchMessage("message1"), fetchMessage("message2")])

  Console.log(messages->Array.joinWith(", "))
}

Js.Promise module (legacy - do not use)

Note: The Js.Promise bindings are following the outdated data-last convention from a few years ago. We kept those APIs for backwards compatibility. Either use Promise or a third-party promise binding instead.

ReScript has built-in support for JavaScript promises. The 3 functions you generally need are:

  • Js.Promise.resolve: 'a => Js.Promise.t<'a>

  • Js.Promise.then_: ('a => Js.Promise.t<'b>, Js.Promise.t<'a>) => Js.Promise.t<'b>

  • Js.Promise.catch: (Js.Promise.error => Js.Promise.t<'a>, Js.Promise.t<'a>) => Js.Promise.t<'a>

Additionally, here's the type signature for creating a promise on the ReScript side:

RES
Js.Promise.make: ( ( ~resolve: (. 'a) => unit, ~reject: (. exn) => unit ) => unit ) => Js.Promise.t<'a>

This type signature means that make takes a callback that takes 2 named arguments, resolve and reject. Both arguments are themselves uncurried callbacks (with a dot). make returns the created promise.

Usage

Using the pipe operator:

ReScriptJS Output
let myPromise = Js.Promise.make((~resolve, ~reject) => resolve(. 2))

myPromise->Js.Promise.then_(value => {
  Console.log(value)
  Js.Promise.resolve(value + 2)
}, _)->Js.Promise.then_(value => {
  Console.log(value)
  Js.Promise.resolve(value + 3)
}, _)->Js.Promise.catch(err => {
  Console.log2("Failure!!", err)
  Js.Promise.resolve(-2)
}, _)
Lazy ValueAsync / Await

© 2024 The ReScript Project

Software and assets distribution powered by KeyCDN.

About
  • Community
  • ReScript Association
Find us on