How can I make waterfall Q promises?

let's take this as an example:

  • I have 3 urls in url array
  • The require function returns a promise that just calls $ http

this is working code, but since the array can be from 1 to n, this is clearly not what I want. I need 3 to be required as a waterfall and not in parallel. in the last promise I need to resolve the final promise that is deferred by var.

require(urls[0]).then(function () {                            
    require(urls[1]).then(function () {                                
        require(urls[2]).then(function () {                                    
            deferred.resolve();
        });
    });
})

      

this approach doesn't work because it will make all the $ http calls in parallel.

var promises = [];
angular.forEach(urls, function (value) {
    promises.push(require(value));
});
$q.all(promises).then(function () {
    deferred.resolve();
});

      

Is there a good way to do this with a for / cycle?

+3


source to share


3 answers


Create a function to handle iterations:



function go (urls) {
    if (urls[0]) {
      require(urls[0]).then(function () {
          go(urls.slice(1));
      });
    }
}

go(urls);

      

+6


source


Here's a great blog post: http://www.codeducky.org/q-serial/

I will only share the part that is relevant.

First, we define this helper method:



function serial(tasks) {
  var prevPromise;
  angular.forEach(tasks, function (task) {
    //First task
    if (!prevPromise) { 
      prevPromise = task(); 
    } else {
      prevPromise = prevPromise.then(task); 
    }
  });
  return prevPromise;
}

      

Then we use it.

serial([
  function() { return require(urls[0]) },
  function() { return require(urls[1]) },
  function() { return require(urls[2]) }
]).then(function () {
    deferred.resolve();
});

      

+2


source


Just to suggest another way, a "one-line" solution without using another method:

return promises.reduce($q.when, promises[0]);

      

See a demo here: http://plnkr.co/edit/xlGxYj57lzXdAMM5Iv6s?p=preview (I've changed the default $q.when

to something else to show how each promise is processed.)

Update: Made the plunker a more personable OP script.

+2


source







All Articles