whins
7/24/2018 - 11:49 AM

ConcurrentQueue.js

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);
});