Reputation: 1931
When we want to execute several then functions one after another in a sequential manner, what is the difference between these two styles:
1- To use nested thens
$http.get('api').then(function(){
processBlocks(obj.data).then(function(){
alert('it is done')
});
});
2- Flatten the nested thens
$http.get('api').then(function(){
return processBlocks(obj.data);
}).then(function(){
alert('it is done')
});
It is obvious that the second one is more readable but is there a performance difference as well?
Upvotes: 3
Views: 88
Reputation: 370769
There might be a very slight performance difference in that the function passed to a .then
is chained with the initial chained Promise when the interpreter runs across the initial Promise on that line. To illustrate, when the Promises are all chained together in a flat manner, the second chained expensiveFunctionThatReturnsFunc()
runs immediately in order to create the function to put in the .then
chain:
const resolveAfter = ms => new Promise(res => setTimeout(res, ms));
const expensiveFunctionThatReturnsFunc = () => {
console.log('making fn...');
// for (let i = 0; i < 999999999; i++) {}
return () => console.log('resolving');
}
console.log('start');
resolveAfter(1000)
.then(() => resolveAfter(1000))
.then(expensiveFunctionThatReturnsFunc());
In contrast, when you have nested .then
s, the expensiveFunctionThatReturnsFunc()
will only run once the first Promise
resolves:
const resolveAfter = ms => new Promise(res => setTimeout(res, ms));
const expensiveFunctionThatReturnsFunc = () => {
console.log('making fn...');
// for (let i = 0; i < 999999999; i++) {}
return () => console.log('resolving');
}
console.log('start');
resolveAfter(1000)
.then(() => {
return resolveAfter(1000)
.then(expensiveFunctionThatReturnsFunc());
});
Still, the effect of such a thing will be completely imperceptible in 99% of situations. Don't worry about it, better to just make your code readable.
Upvotes: 1
Reputation: 727
$http.get('api').then(function(){
processBlocks(obj.data).then(function(){
alert('it is done')
});
});
In this case, if you concatenate another then
like this:
$http.get('api').then(function(){
processBlocks(obj.data).then(function(){
alert('it is done')
});
}).then(function(){
alert('it is done')
});
if processBlocks()
throws an exception, it doesnt matter, and the next promise will be fired, but:
$http.get('api').then(function(){
return processBlocks(obj.data);
}).then(function(){
alert('it is done')
});
In this case, if the first then
fails, the sequence is canceled and in case of having a catch
block, it will be fired
Upvotes: 3