Promises in JavaScript

Sep 10, 2019

In JavaScript, a promise is an object that represents an asynchronous operation. Promises have several methods that let you register a callback that the JavaScript runtime will call when the operation succeeds or fails.

In the below example, the Axios HTTP library returns a promise. You can then use the then() function to register a callback that JavaScript will call when the request succeeds.

const axios = require('axios');

// `axios.get()` returns a promise representing an HTTP request.
const promise = axios.get('https://httpbin.org/get?answer=42');

// The `then()` function lets you register a callback that JavaScript
// will call when the HTTP request succeeds.
promise.then(res => {
  res.data.query.answer; // '42'
});

Promises as State Machines

You can think of a promise as a state machine with 3 states:

  1. Pending The operation is in progress.
  2. Fulfilled The operation completed successfully.
  3. Rejected The operation experienced an error.

When a promise is created, it is always pending. Once a promise is fulfilled or rejected, the promise is considered settled, and can no longer change state. The promise's state is a private property: given a promise, there is no easy way to tell what the promise's state currently is.

When a promise becomes settled, the JavaScript runtime calls any handler functions that you registered using .then(). The then() function takes 2 parameters: onFulfilled and onRejected. JavaScript calls onFulfilled() if the promise is fulfilled, or onRejected() if the promise is rejected.

// Create a promise that is immediately fulfilled with value 42.
const promise = Promise.resolve(42);

const onFulfilled = () => {};
const onRejected = () => {};

// JavaScript will call `onFulfilled` if the promise is fulfilled,
// and `onRejected` if the promise is rejected.
promise.then(onFulfilled, onRejected);

Values and Errors

When a promise is fulfilled, JavaScript sets an associated value. The promise's value is also a private property. The only way to access it is via the .then() function.

// Create a promise that is immediately fulfilled with value 42.
const promise = Promise.resolve(42);

promise.then(value => {
  value; // 42
});

When a promise is rejected, JavaScript sets an associated error. The promise's associated error is also a private property.

// Create a promise that is immediately rejected with an error object
const promise = Promise.reject(new Error('Oops!'));

promise.then(null, err => {
  err.message; // 'Oops!'
});

You can learn more by writing your own promise library from scratch.

The Promise Constructor

Promise is a built-in class in JavaScript. That means you can instantiate a promise using new Promise().

The promise constructor takes 1 parameter: a function called executor. The executor function takes two parameters: callback functions resolve() and reject(). As someone creating a new promise, you're responsible for writing the executor function, and the JavaScript runtime is responsible for passing you resolve() and reject().

const promise = new Promise(function executor(resolve, reject) {
  // Fulfill the promise with value '42' after 100 ms.
  setTimeout(() => resolve(42), 100);
});

promise.then(value => {
  value; // 42
});

More Fundamentals Tutorials