Promises in JavaScript
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:
- Pending The operation is in progress.
- Fulfilled The operation completed successfully.
- 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
});