var concurrentQueue = concurrentQueue || function concurrentQueue(concurrency) {
concurrency = concurrency || 1;
var running = 0;
var taskId = 0;
var taskQueue = [];
var done = function () {};
function onTaskCompleted() {
running--;
console.log("complete " + this.id);
if (!taskQueue.length) {
if (!running) {
typeof done == "function" && done();
running = 0;
taskId = 0;
taskQueue = [];
}
return;
}
runTask(taskQueue.shift());
}
function runTask(taskItem) {
running++;
if (!!taskItem.timeout) {
taskItem.timeoutId = setTimeout(function () {
clearTimeout(taskItem.timeoutId);
taskItem.timeoutId = null;
console.warn("completed " + taskItem.id + " by timeout");
onTaskCompleted.call(taskItem);
}, taskItem.timeout);
}
console.log("run " + taskItem.id);
taskItem.task(function () {
onTaskCompleted.call(taskItem);
});
}
function enqueueTask(task) {
taskQueue.push(task);
}
var r = {
push: function (task, timeout) {
running < concurrency ? runTask({
id: taskId++,
task: task,
timeout: timeout
}) : enqueueTask({
id: taskId++,
task: task,
timeout: timeout
});
return r;
},
done: function (doneTask) {
done = doneTask;
}
};
return r;
};
var q = concurrentQueue(2).push(function (completeTask) {
console.log("task 0 processing...");
setTimeout(function () {
completeTask();
}, 5000);
}).push(function (completeTask) {
console.log("task 1 processing...");
setTimeout(function () {
completeTask();
}, 2000);
});
q.push(function (completeTask) {
console.log("task 2 processing...");
setTimeout(function () {
completeTask();
}, 100);
}).push(function (completeTask) {
console.log("task 3 processing...");
setTimeout(function () {}, 500);
}, 3000).done(function () {
setTimeout(function () {
console.log("completed");
}, 500);
});