mohas
mohas

Reputation: 1931

What is the difference between these two styles for handling sequential Promises

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

Answers (2)

CertainPerformance
CertainPerformance

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 .thens, 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

Ferus7
Ferus7

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

Related Questions