In an attempt to understand promises more clearly, i have been reading up a few very interesting articles on the same. I came across the following code which works perfectly for executing promises sequentially. But i am not able to understand how it works.
function doFirstThing(){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(1);
},1000)
})
}
function doSecondThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(res + 1);
},1000)
})
}
function doThirdThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(res + 2);
},1000)
})
}
promiseFactories = [doFirstThing, doSecondThing, doThirdThing];
function executeSequentially(promiseFactories) {
var result = Promise.resolve(); // this is the most problematic line
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory);// what is happening here ?
});
return result;
}
executeSequentially(promiseFactories)
I do understand that promises are executed as soon as they are created. For some reason i am not able to understand the flow of execution. Especially this following line:
var result = Promise.resolve()//and empty promise is created.
Please if somebody can help me understand how calling the promiseFactory method inside the 'then' method of the empty promise makes it execute sequentially, like so. Or is it because of the forEach loop ?
result = result.then(promiseFactory);
I tried replacing the 'forEach' with a 'map' function and still yielded the same result. i.e, the methods where executed sequentially. Also, how is the value passed from one chained function to other ?
Any help or article/blog is highly appreciated.
You can image a Promise as a box with execution inside. As far as the promise is created, the execution starts. To get the result value, you have to open the box. You can use then
for it:
Promise.resolve(5).then(result => console.log(result)); // prints 5
If you want to chain promises you can do it by opening the box one by one:
Promise.resolve(5)
.then(result => Promise.resolve(result + 1))
.then(result => Promise.resolve(result * 2))
.then(result => console.log(result)); // prints 12
This chaining makes the executions synchronous (one by one).
If you want to execute several promises asynchronously (you don't chain results), you can use Promise.all
:
Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])
.then(result => console.log(result)); // prints [1,2,3]
In your case:
Promise.all(promiseFactories).then(result => console.log(result));
Another option how to work with promises is to await
them:
(async ()=> {
var res1 = await Promise.resolve(5);
var res2 = await Promise.resolve(res1 + 1);
var res3 = await Promise.resolve(res2 * 2);
console.log(res3); // prints 12
})();
await
works similar to then
- it makes asynchronous execution to synchronous.
In your case:
async function executeSequentially(promiseFactories) {
for (const p of promiseFactories) {
const result = await p;
console.log(result);
}
}
Note: await
packs a value into a Promise out of the box:
var res1 = await 5; // same as await Promise.resolve(5)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With