2

Got an issue with angularjs and some promises. For some reason, my services mix answers on queries, and while services are fixed I need to change my $q.all() to instead of running all promises asynchronously, run then in sequence.

Right now, it looks like this :

var promises = [p1, p2, p3];

$q.all(promises).then(function () {
    // All promises are done
}).catch(function (exception) {
    // An error occured.
});

Expected behaviour should be like p1.then(p2).then(p3);, and order does not matter (since normally run async). Array lenght is variable.

Since $q is inspired by Q lib, I looked in Q documentation and found a sequence reference but couldn't make it work with $q.

Can anyone recommand an easy solution for such issue ?

I did tryed this promises.reduce($q.when, $q(initialVal)); but don't understand what initialVal refere to :(

Thanks for reading, and have a nice day.

sebastienbarbier
  • 6,542
  • 3
  • 29
  • 55
  • something needs to fire off these asynchronous requests. So first of all group these functions and order them in priority. Next, wire up each resolve to fire off the next function. I would just create your own service which does this. – Callum Linington Sep 24 '15 at 10:07
  • Yes my first idea would be a recursive function to trigger the first one, then pop the array and call again after succeed. Not a lot of coding, but not really js style I am affraid. If I do not have an answer, I'll do something by myself and publish here (addd in $q prototype for easy re-use) – sebastienbarbier Sep 24 '15 at 10:11
  • `initialValue` is the input into the first async function in the array, except, I don't think you need `$q` there – New Dev Sep 24 '15 at 10:46
  • 2
    possible duplicate of [How do I sequentially chain promises with angularjs $q?](http://stackoverflow.com/questions/25704745/how-do-i-sequentially-chain-promises-with-angularjs-q) – Estus Flask Sep 24 '15 at 11:06
  • Damned, sorry for duplicate ... don't know why I could not find it :( – sebastienbarbier Sep 24 '15 at 12:29

1 Answers1

6

If you already have promises, the asynchronous methods are already fired! You have to fire them one by one, so your array needs to contain functions that return promises rather than promise objects.

You can then go about it like this, which is clearer to me than the shortcut from Q you provided in your question:

var promiseReturningFunctions = [p1, p2, p3];
var queueEntryPoint = $q.defer();
// create a waiting queue
var queue = queueEntryPoint.promise;
// this queues up the asynchronous functions
promiseReturningFunctions.forEach(function (p) {
    queue = queue.then(p);
});
// here we start processing the queue by resolving our queueEntryPoint
queueEntryPoint.resolve();
// we can now use queue.then(...) to do something after all promises in queue were resolved
queue.then(function () {
    // All promises are done
}).catch(function (exception) {
    // An error occured.
});
Kevin Dreßler
  • 447
  • 2
  • 15
  • 1
    where is `promiseReturningFunctions` being used? – Callum Linington Sep 24 '15 at 10:23
  • My bad, i was changing variable names for better teaching and left one out, see my edit. – Kevin Dreßler Sep 24 '15 at 10:23
  • 1
    It looks fine. Resolved entry point can be added with '$q.when()'. And it will need additional measures for supplying object methods as 'then' callbacks. – Estus Flask Sep 24 '15 at 10:57
  • The entity which inserts into the intial array has to take care of proper binding, if the asynchronous callback function `foo.bar` makes use of `this`, then you would just add it to the array as `promiseReturningFunctions.push(foo.bar.bind(foo))`. I see no real reason for downvote. – Kevin Dreßler Sep 24 '15 at 11:12
  • Ok it works really nice in my case, thanks a lot for your help ;) – sebastienbarbier Sep 24 '15 at 12:28
  • I found I had to make the promiseReturningFunctions factory functions, otherwise it would not work properly (execute immediately and not in sequence). See the possible duplicate question mentioned in the comments section of the question: http://stackoverflow.com/questions/25704745/how-do-i-sequentially-chain-promises-with-angularjs-q – Ben Jun 27 '16 at 07:09