Skip to content

Instantly share code, notes, and snippets.

@stevenpack
Created September 2, 2015 01:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevenpack/8ed09cfbe886c0ecf785 to your computer and use it in GitHub Desktop.
Save stevenpack/8ed09cfbe886c0ecf785 to your computer and use it in GitHub Desktop.
Execute promises in batches
/**
* Created by steve on 1/09/15.
*/
var q = require('q');
function Task(fn, arg) {
this.fn = fn;
this.arg = arg;
}
var state = {};
state.in_progress = 0;
state.started = 0;
state.finished = 0;
var tasks = [];
for (var i = 0; i < 17; i++) {
var fn = function hello_async(obj) { return hello(q.defer(), state, obj)};
var task = new Task(fn, i);
tasks.push(task);
}
console.log(tasks.length + " functions to execute");
var promise = q_batch(q.defer(), tasks, 5);
promise.then(function(data) {
console.log(state.started + " functions started");
console.log(state.finished + " functions finished");
}, function(err) {
console.error(err.stack ? err.stack : err);
});
function q_batch($q, tasks, batch_size) {
//Finished?
if (!tasks || tasks.length == 0) {
$q.resolve(tasks);
console.log("Finished");
return;
}
//Call the function batch_size times to get the promises
var promise_arr = [];
for (var i = 0; (i < batch_size) && (i < tasks.length); i++) {
try {
var task = tasks[i];
console.log("Calling " + task.fn.name + " with " + task.arg);
promise_arr.push(task.fn.call(this, task.arg));
} catch (e) {
$q.reject("Batch failed. " + e);
}
}
//Execute the batch_size, then go again
var promise_batch = q.all(promise_arr);
promise_batch.then(function(results) {
try {
//Remove the first n funcs and go again.
tasks.splice(0, batch_size);
q_batch($q, tasks, batch_size);
} catch (err) {
console.error(err.stack ? err.stack : err);
}
}, function(err) {
$q.reject("Batch failed. " + err);
});
return $q.promise;
}
function hello($q, state, my_num) {
state.in_progress++;
state.started++;
setTimeout(function(){
console.log("Hello world. " + state.in_progress + " in progress. I am: " + my_num);
//if (state.finished == 13) {
// throw "awight!";
//}
//if (state.finished == 13) {
// $q.reject("unlucky number 13");
//}
state.in_progress--;
state.finished++;
$q.resolve(state);
}, Math.random() * 1000);
return $q.promise;
}
@jkrot
Copy link

jkrot commented Feb 28, 2016

This helped me alot to figure out a good way to recursively call my promise chain batch, thanks for putting it out there.

@builtbylane
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment