Promises
Learn about promises, promises/A+, and thenables and how they work, and also the concept of promisification in Node.js.
We'll cover the following...
Promises are part of the ECMAScript 2015 standard (or ES6, which is why they’re also called ES6 promises) and have been natively available in Node.js since version 4. But the history of promises goes back a few years earlier, when there were dozens of implementations around, initially with different features and behaviors. Eventually, the majority of those implementations settled on a standard called Promises/A+.
Promises represent a big step ahead toward providing a robust alternative to continuation-passing style callbacks for propagating an asynchronous result. As we’ll see, the use of promises will make all the major asynchronous control flow constructs easier to read, less verbose, and more robust compared to their callback-based alternatives.
What’s a Promise
?
A Promise
is an object that embodies the eventual result (or error) of an asynchronous operation. In promises jargon, we say that a Promise
is pending when the asynchronous operation is not yet complete, it’s fulfilled when the operation successfully completes and rejected when the operation terminates with an error. Once a Promise
is either fulfilled or rejected, it’s considered settled.
To receive the fulfillment value or the error (reason) associated with the rejection, we can use the then()
method of a Promise
instance. The following is its signature:
promise.then(onFulfilled, onRejected)
In the preceding signature, onFulfilled
is a callback that’ll eventually receive the fulfillment value of the Promise
, and onRejected
is another callback that’ll receive the reason for the rejection (if any). Both are optional.
To have an idea of how promises can transform our code, let’s consider the following callback-based code:
asyncOperation(arg, (err, result) => {if(err) {// handle the error}// do stuff with the result})
Promises allow us to transform this typical continuation-passing style code into a better structured and more elegant code, such as the following:
asyncOperationPromise(arg).then(result => {// do stuff with result}, err => {// handle the error})
In the code above, asyncOperationPromise()
is returning a Promise
, which we can then use to receive the fulfillment value or the rejection reason of the eventual result of the function. So far, it seems that there’s nothing major going on, but one crucial property of the then()
method is that it synchronously returns another Promise
.
Moreover, if any of the onFulfilled
or onRejected
functions return a value Promise
returned by the then()
method will:
Fulfill with
...