leonardofed
leonardofed

Reputation: 976

How to chain promises

In this simplified example, I am calling three functions when the first promise gets resolved.

var test = new Promise(function (res, err) { setTimeout(res, 3000) })

test.then( () => { console.log("A") });
test.then( () => { 
    return new Promise(function(res, err) { 
        setTimeout(()=> { console.log("C"); 
        res() }, 3000) 
    }); 
});

test.then( () => { console.log("B") });

The output as expected is A B C.

Let's suppose that I want to invoke the third .then to console B only when the second promise gets resolved.

If I try to store the second promise (myProm) in global and attach a .then function on it, I'll get (reasonably) a TypeError because at compile time myProm is still undefined.

var test = new Promise(function (res, err) { setTimeout(res, 3000) })
var myProm;

test.then( () => { console.log("A") });
test.then( () => { 
    myProm = new Promise(function(res, err) { 
        setTimeout(()=> { console.log("C"); 
        res() }, 3000) 
    })
    return myProm;
});

myProm.then( () => { console.log("B") });

How do I proceed? What's the best way to chain two promises together so that the returned Promise obj from one .then needs to get resolved before we can execute the next then.

In this scenario, the output I'd like to have would be A C B

Upvotes: 0

Views: 70

Answers (2)

JLRishe
JLRishe

Reputation: 101652

then returns a promise that resolves when the indicated function has run and the value it returned has resolved (this is a slight oversimplification, but sufficient for the task here).

Therefore, to chain a promise on the result of a then. Just tack on another .then:

var test = new Promise(function (res, err) { setTimeout(res, 3000) })

test.then( () => { console.log("A") });
test
    .then( () => { 
        return new Promise(function(res, err) { 
            setTimeout(()=> { console.log("C"); res() }, 3000);
        });
    })
    .then( () => { console.log("B") });

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370639

Each time you call .then, you create a new Promise that resolves when the Promise returned by that .then resolves. You should assign the result of the myProm-containing .then to a variable, and then call .then on that variable:

var test = new Promise(function (res, err) { setTimeout(res, 500) })
var myProm;

test.then( () => { console.log("A") })
  .then( () => { 
      myProm = new Promise(function(res, err) { 
          setTimeout(()=> { console.log("C"); 
          res() }, 500) 
      })
      return myProm;
  })
  .then( () => { console.log("B") });

Most of the time when using Promises, you should be chaining .thens like this. Only do prom.then(...) ... prom.then(...) when you want to initialize two completely separate asynchronous operations when the prom resolves.

Upvotes: 1

Related Questions