简体   繁体   中英

chaining nested promises in a loop

I am kind of new to promises and are stuck on the following exercise.

I have an array of values and I want to execute an async call on each one. In the callback, I want to execute another call on the outcome of the first call.

Basically, my frustration is in the following: The order of execution should be '1x2x3x' but the order is '123xxx'

In other words, the loop is already going to the next iteration when the sub/nested promise of the first promise is not fullfilled yet..

var values = ["1", "2", "3"];

function do(val) {
  var deferred = Q.defer();


  asyncCall(val)
  .then( function( response ) {
    console.log(val); 
    asyncCall(response)
    .then( function ( response ) {
      console.log('x');
      deferred.resolve(true)
    });
  });

  return deferred.promise;
}

var result = do(values[0]);

values.forEach( function(f) {
  result = result.then(do(f));
}

There is probably an easy solution but I'm stuck on it.

You don't need the deferred, that's the deferred anti pattern you have there since promises chain.

Also, you have to return a promise from a .then handler if you want it to wait for it to resolve.

You can simply use a for loop:

function do(val) {

  var q = Q();
  for(var i = 0; i < val; i++){
    q = q.then(asyncCall.bind(null,i))
         .then(console.log.bind(console))
         .then(console.log.bind(console,"x"));
  }

  return q; // in case you want to chain
}

fiddle .

Note: Bind just fixates the value for the function call. In this case since the first param (the this value) is null it acts like function(fn,arg){ return function(arg){ return fn(arg); }} function(fn,arg){ return function(arg){ return fn(arg); }} that is, it translates a function call to a "partial application" - for more info see the MDN docs .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM