3

Tools: JavaScript ES6

I haven't seen a good succinct answer about the syntax of chaining multiple promises to execute in order. I thought this would be a good nail in the coffin question for all promise newbies out there. :)

My Issue is that I want to call this in a synchronous order getPosts--->getThreads--->initializeComplete()

Here is what I am doing.

userPromise.then(getPostsPromise).then(getThreadsPromise).then(initializeComplete()); 
  • userPromise is Promise obj I returned from another part of the code
  • getPostsPromise returns a Promise and makes a fetch to the server for posts
  • getThreadsPromise returns a Promise and makes a fetch to the server for threads
  • initializeComplete is a callback to tell my program that it is initialized.

Here is an example of one of the promises in the chain:

var getPostsPromise = function(){ //Firebase is just a simple server I'm using var firebasePostsRef = new Firebase("https://myfburl.firebaseio.com/posts"); var postsRef = firebasePostsRef.child(localPlace.key); return new Promise(function(resolve, reject) { //Below is a Firebase listener that is called when data is returned postsRef.once('value', function(snap,prevChild) { var posts = snap.val(); AnotherFile.receiveAllPosts(posts); resolve(posts); }); }); } 

But initializeComplete() is being called before getPostsPromise and getThreadsPromise have a chance to finish fetching.

Why is that happening and how do I write the promises to execute in order?

10
  • 2
    You have to return something from your promise chain to wait for finish each Commented Nov 2, 2015 at 2:48
  • @Michael what if someone doesn't need to transfer anything to the next promise and they just need to run in order(btw should I add that into the question?) Commented Nov 2, 2015 at 2:50
  • 1
    Doesn't matter, just do nothing with it, only the return part is important Commented Nov 2, 2015 at 2:51
  • 1
    then(()=>getPostsPromise).then... Commented Nov 2, 2015 at 2:59
  • 2
    For starters, you might want to try removing the parenthesis from initializeComplete()... Commented Nov 2, 2015 at 3:14

2 Answers 2

7

initializeComplete is getting called right away because you are invoking it when passing it to then. You have to omit the parentheses, just like you did for getPostsPromise and getThreadsPromise

userPromise.then(getPostsPromise).then(getThreadsPromise).then(initializeComplete); 
Sign up to request clarification or add additional context in comments.

5 Comments

This seems like the simple answer here.
This worked for me! Thx a TON everybody for the help. So no return value is needed in the chain when the method returns a new Promise?
Yes, the code you had was fine. Just had that little parens mistake. When the function you pass in returns a promise, the next function passed in will wait for that promise to be resolved and will get passed the value you resolved the previous promise with. Check out this article if you haven't already html5rocks.com/en/tutorials/es6/promises. Thanks Matthew for making me aware of this.
the return value of the method is a promise
Thanks to both of you @yts and Matthew this will be a very useful for others who will eventually need it.
4

While yts's answer is correct (the issue is you're invoking initializeComplete instead of passing the function), I'd rather format the calls a bit differently. Having each callback function call the next function is a bit against the design of promises. I'd rather each function return a promise, and then call then on the returned promise:

userPromise .then(function(){ return getPostsPromise() }).then(function(){ return getThreadsPromise() }).then(function(){ return initializeComplete(); }); 

or to pass the actual returned objects and not have to do any additional intermediate processing:

userPromise .then(getPostsPromise) .then(getThreadsPromise) .then(initializeComplete); 

9 Comments

This method would still be synchronous, it would call getPostsPromise, once that promise gets resolved it would call getThreadsPromise and once that promise gets resolved calls initializeComplete
Ah, yes you're correct. I didn't know about the magic that waits for the promise if that's what's returned in the then function. Cool :) Edited my answer.
When I do it this way the things I "resolve" in the Promises are undefined in the next promise. How do I pass it along using the format above?
you could provide each of the functions with the parameters and pass that through to the next function. Or do like userPromise.then(getPostsPromise). which will pass the response of userPromise to getPostPromise
If you have no custom arguments for the functions, there is no reason to be more verbose like this than what the yts answer shows. This does not change the behavior and just makes more code.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.