3

I am straggling with chaining two promises inside a loop, so that promise number two, does not start until promise one has been resolved.

I saw an example with reduce. Could not get it to work, yet. If I just do then, as I currently have, the code executes in parallel - as in, all async requests are fired off, and of course the results are messed-up. Please take a look:

for ( var i = 0; i < dummyData.accounts.length; i++) {
  var cursorUser = dummyData.accounts[i];
  var auth0User = {
    email: cursorUser.email,
    password: 'abc123',
    connection: 'Username-Password-Authentication'
  };
  createUser(api, auth0User)
    .then(function (auth0Info) {
      return auth0Info;
    })
    .then(function(auth0Info) {
      cursorUser.authProfile = auth0Info;
      console.log("account: ", cursorUser);
      return create(accountsAPIService, cursorUser);
    })
}
2
  • See the all method. Commented Jan 5, 2016 at 15:31
  • What version of node is this? Commented Jan 5, 2016 at 15:44

2 Answers 2

4

Simply avoid for loops for asynchronous work.

Arrays have functional methods like forEach and map for this kind of thing.

var pendingResults = dummyData.accounts.map(function (account) {
    return createUser(api, {
        email: account.email,
        password: 'abc123',
        connection: 'Username-Password-Authentication'
    }).then(function (authInfo) {
        console.log("account: ", authInfo);
        return create(accountsAPIService, authInfo);
    });
});

Promise.all(pendingResults).then(function (results) {
    // everything is done
});
Sign up to request clarification or add additional context in comments.

Comments

2

See @Tomalak's answer for the actual solution.


The problem is that a for clause does not create a new scope for the variables. In other words, you code is understood as:

var i, cursorUser, auth0User;
for (i = 0; i < dummyData.accounts.length; i++) {
  cursorUser = dummyData.accounts[i];
  auth0User = {
    // ...
  };
  // ...
}

When the async promise is resolved, another iteration probably has already overwritten the cursorUser variable: the then callback cannot read the value of the iteration that started its promise anymore.

3 Comments

This is technically correct but unfortunately not very elegant. There's no need to put up with for loops in asynchronous contexts.
@Tomalak You're absolutely right, code review FTW :)
I was hesitant of paraphrasing your answer in mine, so I didn't. Good compromise.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.