Promises are helping to deal with asynchronous operations in JavaScript.
Lets create basic promise:
EcmaScript 5:
var promise = new Promise(function(resolve, reject) { // 1
setTimeout(function() {
resolve('Second');
}, 500);
});
promise.then(function(value) { // 2
console.log(value); // 4
});
console.log('First'); // 3
EcmaScript 6:
const promise = new Promise((resolve, reject) => { // 1
setTimeout(() => {
resolve('Second');
}, 500);
});
promise.then((value) => { // 2
console.log(value); // 4
});
console.log('First'); // 3
Additionally function can be excluded from Promise:
const promiseFunc = (resolve, reject) => { // 1
setTimeout(() => {
resolve('Second');
}, 500);
}
const promise = new Promise(promiseFunc);
promise.then((value) => { // 2
console.log(value); // 4
});
console.log('First'); // 3
our console will show us:
First
Second
The “First” console.log will be visible immediately. “Second” will be visible after 500ms. So what happend? Created promise (1) had been invoked (2). When promise is done
resolve is invoked and parameter ‘Second’ was passed. So when promise is done console.log will display value from our Promise.
const explode = (string) => string.split('');
const getSecond = (array) => array[2]
const promise = new Promise((resolve, reject) => { // 1
setTimeout(() => {
resolve('Second');
}, 500);
});
promise
.then(v => explode(v))
.then(v => getSecond(v))
.then(v => console.log(v));
const explode = (string) => string.split('');
const getSecond = (array) => array[2]
const promise = new Promise((resolve, reject) => { // 1
setTimeout(() => {
resolve('Second');
}, 500);
});
promise
.then(v => explode(v))
.then(v => getSecond(v))
.then(v => console.log(v))
.finally(() => console.log('finally'));
There are situations when we need to wait for few asynchronous operations. In this case we can use Promise.all(). This function gets array of promises as an argument and waits for all promises. Lets check how our sample will behave:
const promise01 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('10ms');
}, 10);
});
const promise02 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('500ms');
}, 500);
});
const promise03 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('900ms');
}, 900);
});
Promise
.all([promise01, promise02, promise03])
.then(val => {
console.log(val)
})
As a result in console we will see:
["10ms", "500ms", "900ms"]
As you can see this is array of results in same order as it was initiated. What will happen when one of our promises won’t be resolved and will reject? Lets get to next subsection.
In this subsection we will check how Promise.all() will behave.
const promise01 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('10ms');
}, 10);
});
const promise02 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('500ms');
}, 500);
});
const promise03 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('ERROR');
}, 900);
});
Promise
.all([promise01, promise02, promise03])
.then(val => {
console.log(val)
})
Our Promise.all() wont return anything as it has error and its not catched properly. To catch it we need to change code a bit
const promise01 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('10ms');
}, 10);
});
const promise02 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('500ms');
}, 500);
});
const promise03 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('ERROR');
}, 900);
});
Promise
.all([promise01, promise02, promise03])
.then(val => {
console.log(val)
})
.catch(err => {
console.log("error: ", err);
})
Now we are adding catch() (in selected lines 24-26) to our Promise.all(). This will handle reject() from promise03. err parameter of catch() will be equal ‘ERROR’ as it is a parameter passed to reject() function in promise03.