1

I want to bind promises sequentially, inside a loop. I need this to user accounts, where the result of one operation depends on another. I am trying to write a flat version - all code in one place, using bind. That's at least what I wanted. I wrapped promises around two create methods, as below:

function create(myApi, record) { return new Promise(function (resolve, reject) { myApi.create(record, function (err, result) { if (err) reject(err); else resolve(result); }); }); } function createUser(myApi, record) { return new Promise(function (resolve, reject) { myApi.createUser(record, function (err, result) { if (err) reject(err); else resolve(result); }); }); } 

Now, I want to create users in a loop as:

for ( var i = 0; i < dummyData.accounts.length; i++) { var cursorUser = dummyData.accounts[i]; var auth0User = { email: cursorUser.email, password: cursorUser.password, connection: 'Username-Password-Authentication' }; createUser(api, auth0User) .then( function(auth0Info) { console.log("Auth0 userInfo: ", auth0Info); cursorUser.authProfile = auth0Info; create(accountsAPIService, cursorUser) .then(function (account) { console.log("created account:", account); }) .catch(function (err) { console.log('count not create account for user, error: ', err, '\nfor: ', auth0User); }); }) .catch(function (err) { console.log('could not create auth0 user, error: ', err, '\nfor: ', auth0User); }); } 

Since the two method are asynchronous, it is of course not working correctly. Calls are not executed sequentially. I want to chain promises so that create does not run until a call from createUser returned. Tried using bind, but it did not work for me. It is how one should do the sequential chaining? I bind on .then of the createUser? Please advise.

5
  • blog.slaks.net/2015-06-10/advanced-promise-usage Commented Jan 4, 2016 at 14:00
  • Hey is ES6 an option?if so moving to generators would make your life so much easier Commented Jan 4, 2016 at 14:02
  • @itai Thank you for noticing my question. ES6 might be an option. Regardless, I would love to know how this could be done with ES6, if nothing else. Commented Jan 4, 2016 at 14:17
  • @MosheShmukler wrote answer hope it will help Commented Jan 4, 2016 at 16:27
  • @itai Yes, thank you. I believe that I figured out how to use bind, but it is definitely nice to know how things could work under es6. At work, my colleagues do lots of typescript->es6->es5 with babel. It is too advanced for me at the moment, but I will certainly try to understand your example. Commented Jan 4, 2016 at 17:35

2 Answers 2

3

When you return a promise from a then, the then chained after will resolve/reject with that promise instead of the original promise.

createUser(api, auth0User).then(function(auth0Info) { cursorUser.authProfile = auth0Info; // Return create's promise return create(accountsAPIService, cursorUser); }, function (err) { console.log('could not create auth0 user, error: ', err, '\nfor: ', auth0User); }) // This will wait for create's promise instead of createUser's promise .then(function (account) { console.log("created account:", account); }, function (err) { console.log('count not create account for user, error: ', err, '\nfor: ', auth0User); }) 
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the answer. I am not positive that you are correct, here. At least my data looks wrong. I might be messing it up myself. From my tests, it does not look like the loop is waiting.
I am pretty sure that these promises are being executed in parallel and not sequentially. Yet, I know nothing about this and still don't understand the subject. I might be wrong.
you were nearly on the spot. First then needs to be replaced for bind.
0

Using ES6 you can use generators which allows you to do write async task as they were async. In this example i am using bluebird but ofc there are others great valid options.

var CreateUserGenerator = BPromise.coroutine(function * (arg) { for ( var i = 0; i < dummyData.accounts.length; i++) { var cursorUser = dummyData.accounts[i]; var auth0User = { email: cursorUser.email, password: cursorUser.password, connection: 'Username-Password-Authentication' }; var auth0Info = yield createUser(api, auth0User); console.log("Auth0 userInfo: ", auth0Info); cursorUser.authProfile = auth0Info; var account = yield create(accountsAPIService, cursorUser) console.log("created account:", account); } } function generateorWithCatch (argument) { creatLoopUser(arg) .catch(function (err) { console.log('could not create auth0 user, error: ', err, '\nfor: ', auth0User); }); } 

In this solution i assume your create and createUser functions are written and return value correctly

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.