function somethingAsync(item, fn) {
setTimeout(function() {
fn(item * 2);
}, Math.random() * 1000);
}
function processQueue(parallel, queue, cb) {
var index = 0;
var pending = 0;
var processed = [];
function dequeue() {
var item = queue.shift();
if( item ) {
var position = index;
index++;
pending++;
somethingAsync(item, function(result) {
processed[position] = result;
pending--;
if( queue.length ) {
dequeue();
} else if( pending === 0) {
cb( processed );
}
});
}
}
for(var i = 0; i < parallel && i < queue.length; i++) {
dequeue();
}
}
processQueue(5, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20], function(processed) {
console.log(processed);
});
// [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]