I am using the Q javascript promises library and am running in a browser, and I want to figure out how to chain together groups of promises so that each group gets executed sequentially. For example, if I have items A, B, C, and D, I want to group A and B together and then C and D together, so that both A and B must fulfill before C and D get executed. I created this simple jsfiddle to show my current attempt.
var work_items = [ 'A','B','C','D','E','F','G','H','I' ];
var n = 2; // group size
var wait = 1000;
var getWorkPromiseFn = function (item) {
log("Getting promise function for " + item);
return function () {
log("Starting " + item);
var deferred = Q.defer();
setTimeout(function () {
var status = "Finished " + item;
log(status);
deferred.resolve(status);
}, wait);
return deferred.promise;
};
};
var queue = Q();
//log('Getting sequentially'); // One-by-one in sequence works fine
//work_items.forEach(function (item) {
// queue = queue.then(getWorkPromiseFn(item));
//});
log('Getting ' + n + ' at a time'); // This section does not
while (work_items.length > 0) {
var unit = [];
for (var i=0; i<n; i++) {
var item = work_items.shift();
if (item) {
unit.push(getWorkPromiseFn(item));
}
}
queue.then(Q.all(unit));
}
var inspect = queue.inspect(); // already fulfilled, though no work is done
It looks like I am probably passing the wrong array to Q.all
here, since I'm passing in an array of functions which return promises rather than an array of the promises themselves. When I tried to use promises directly there (with unit.push(Q().then(getWorkPromiseFn(item));
for example), the work for each was begun immediately and there was no sequential processing. I guess I'm basically unclear on a good way to represent the group in a way that appropriately defers execution of the group.
So, how can I defer execution of a group of promises like this?