0

I am using Typescript to write JS promises. I have a compound promise, i.e. promise which returns a promise I have:

test() {
    addElement("first")
        .then(
            function (val){
                addElement("second");
                console.log("second*);
            })
            .then(
            function (val){
                addElement("third");
                console.log("third*");
            });
}


export function addElement(elementText){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve();
        }, Math.random() * 2000);
    })
    .then(console.log(elementText));
}

I would like these functions to print out, first, second*, second, third*, third. However, I get:

JS: first JS: second* JS: third* JS: third JS: second

How do I get the then to execute after the called promises' then has completed?

George Edwards
  • 8,979
  • 20
  • 78
  • 161
  • Promises are resolved on next iteration of the event loop, by design. – zerkms May 31 '16 at 21:55
  • @zerkms Is there a way to execute some code only after all the addElement logic is executed? Like an onCompletion event? – George Edwards May 31 '16 at 21:59
  • You can use Promise.all() that also would take in count the execution order. – Jose Hermosilla Rodrigo May 31 '16 at 22:00
  • @GeorgeEdwards yes there is - use `.then()` – zerkms May 31 '16 at 22:04
  • 1
    First off, change `.then(console.log(elementText));` to `.then(function() {console.log(elementText)})` so it is not called immediately, but is instead called when the promise resolves. You need to pass a function reference to `.then()`. You were executing the function immediately and then passing the return result of that function which is `undefined`. – jfriend00 May 31 '16 at 23:41
  • 1
    Possible duplicate of [How to make compound promises execute asynchronously](http://stackoverflow.com/questions/37534070/how-to-make-compound-promises-execute-asynchronously) –  Jun 01 '16 at 01:27

1 Answers1

0

You're not returning your promise in the then block. If you don't return the promise, then the then block will return undefined immediately, and nothing will wait for it. If you return a promise instead, then execution of the promise chain will pause until the promise you return has been satisfied.

test() {
    addElement("first")
        .then(
            function (val){
                console.log("second*");
                return addElement("second");
            })
            .then(
            function (val){
                console.log("third*");
                return addElement("third");
            });
}

Though I don't personally consider it a "rookie mistake", your description matches "Rookie Mistake #5" in Nolan Lawson's "We have a problem with promises"; read on for a more in-depth explanation.

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251