JS promise
last modified October 18, 2023
In this article we show how to work with promises in JavaScript.
A represents a potential value, or error, that will be available at some time in the future.
A Promise can have one of the states:
- pending - initial state, neither fulfilled nor rejected
- fulfilled - the operation was completed successfully
- rejected - the operation has failed
We work with promises using either callbacks or async/await keywords.
Promises are called futures in some programming languages.
JS Promise.resolve
The Promise.resolve
method returns a Promise object that is
resolved with a given value.
let promise = new Promise(resolve => { setTimeout(() => resolve(2), 2000); }); promise.then(val => console.log(val)); console.log('finished');
We create a promise which resolves after two seconds with an integer value. The
then
function attaches callbacks for the resolution and/or
rejection of the promise.
$ node main.js finished 2
In the next example, we use the async/await keywords.
async function doWork() { let res = await promise; console.log(res); } let promise = new Promise(resolve => { setTimeout(() => resolve(2), 2000); }); doWork(); console.log('finished');
The await
keyword is used to wait for a Promise. It can only be
used inside an async function.
JS promise error
The Promise.reject
method returns a Promise object that is rejected
with a given reason.
let promise = new Promise((resolve, reject) => { let b = Math.random() < 0.3; if (b) { resolve(10); } else { reject("promise error"); } }); promise.then(val => console.log(val)).catch(err => { console.log(`${err}`) }); console.log('finished');
In the example, we simulate an error with Math.random
. We catch
the error with catch
method.
$ node main.js finished promise error $ node main.js finished promise error $ node main.js finished 10
JS chaining promises
It is possible to execute multiple asynchronous operations with chaining.
let p = new Promise((resolve) => { resolve(1); }); let r = p.then(val => val + 2).then(val => val + 3) .then(val => val + 4).then(val => console.log(val)); console.log('finished');
The example adds four integers via chaining of promises.
$ node chain.js finished 10
JS Promise.all
The Promise.all
method takes an iterable of promises as a parameter
and returns a single promise that resolves to an array of the results of the
given promises.
This returned promise resolves when all promises have resolved. It rejects immediately upon any of the input promises rejecting with error.
const p1 = new Promise((resolve) => setTimeout(resolve, 100, 100)); const p2 = new Promise((resolve) => setTimeout(resolve, 300, 200)); const p3 = new Promise((resolve) => setTimeout(resolve, 500, 300)); const promises = [p1, p2, p3]; Promise.all(promises).then((data) => console.log(data.reduce((total, next) => total + next))); console.log('finished');
In the example, we wait for all promises to finish and in the end, we calculate the sum of returned values.
$ node all.js finished 600
JS multiple requests with axios
In the next example, we use the axois library to execute multiple get requests. Axios is a promise-based HTTP client for Node and the browser.
$ npm i axios
We install the Axios library.
const axios = require('axios'); async function makeRequests(urls) { const fetchUrl = (url) => axios.get(url); const promises = urls.map(fetchUrl); let responses = await Promise.all(promises); responses.forEach(resp => { let msg = `${resp.config.url} -> ${resp.headers.server}: ${resp.status}`; console.log(msg); }); } let urls = [ 'http://webcode.me', 'https://example.com', 'http://httpbin.org', 'https://clojure.org', 'https://fsharp.org', 'https://symfony.com', 'https://www.perl.org', 'https://www.php.net', 'https://www.python.org', 'https://code.visualstudio.com', 'https://github.com' ]; makeRequests(urls);
We wait for all requests to finish with Promise.all
. After
completion, we go through the array of responses and server name and response
status.
$ node main.js http://webcode.me -> nginx/1.6.2: 200 https://example.com -> ECS (dcb/7ECA): 200 http://httpbin.org -> gunicorn/19.9.0: 200 https://clojure.org -> AmazonS3: 200 https://fsharp.org -> GitHub.com: 200 https://symfony.com -> cloudflare: 200 https://www.perl.org -> Combust/Plack (Perl): 200 https://www.php.net -> myracloud: 200 https://www.python.org -> nginx: 200 https://code.visualstudio.com -> Microsoft-IIS/10.0: 200 https://github.com -> GitHub.com: 200
JS create PDF with Puppeteer
In the following example, we genearate a PDF file from a webpage using the Puppeteer library.
$ npm i puppeteer
We install Puppeteer.
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('http://webcode.me'); await page.pdf({ path: 'webcode.pdf', format: 'a5' }); await browser.close(); })();
The whole task consists of several asynchronous operations, which are handled with async/await keywords.
Source
JS Promise - language reference
In this article we have worked with promises in JavaScript.