The following code
function doSomething(msg){
return new Promise((resolve, reject) => {
setTimeout(
() => {
console.log(msg);
resolve();
},
2000);
})
}
let start = Date.now();
let end;
doSomething("1st Call")
.then(()=>doSomething("2nd Call"))
.then(()=>doSomething("3rd Call"))
.then(()=>{
end = Date.now();
console.log('start',start);
console.log('end',end);
console.log('elapsed time',end-start);
})
prints 1st Call, 2nd and 3rd, with 2 seconds between each console.log statement, as expected
However, if I remove the arrow functions from the then blocks, the behaviour is totally different, i.e
doSomething("1st Call")
.then(doSomething("2nd Call"))
.then(doSomething("3rd Call"))
.then(()=>{
end = Date.now();
console.log('start',start);
console.log('end',end);
console.log('elapsed time',end-start);
})
With this code, all the console.log statements get printed at the same time, and the elapsed time is just 2 seconds, as opposed to 2 seconds per function (6 seconds total as in the first example)
In other words, for the code to work correctly, the then function needs to take a function (the arrow one in this case), and from inside that function, then I can do further function calls.
Why can't I just pass the function directly, why does it need to be nested in another function?
.then()
expects a callback function which will be called when the Promise
on which .then()
method is called - fulfills.
When you do this
.then(doSomething("2nd Call"))
instead of registering a callback function which will be invoked at some later time, doSomething()
is called immediately.
You could pass a reference to a function to the .then()
method and .then()
will call that function when Promise
fulfills.
.then(doSomething)
but you won't be able to pass any argument to doSomething
function.
.then(doSomething("2nd Call"))
will only work if doSomething
returns a function. In that case, returned function will be registered as a callback and will be called when Promise
fulfills.
You could use .bind()
to get a function which will be used as a callback to .then()
method
function doSomething(msg){
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(msg);
resolve();
}, 2000);
});
}
let start = Date.now();
let end;
doSomething("1st Call")
.then(doSomething.bind(null, '2nd Call'))
.then(doSomething.bind(null, '3rd Call'))
.then(()=>{
end = Date.now();
console.log('start',start);
console.log('end',end);
console.log('elapsed time',end-start);
})