首页 > 代码库 > javascript 多线程异步队列

javascript 多线程异步队列

首先,你得知道 jQuery.Deferred 的大致用法,然后,我们进入正题吧:

库代码:

/*! * 多线程异步队列 * 依赖 jQuery 1.8+ (如果你用的是 1.6或1.7, 只要将源码中的 then方法替换为pipe方法 即可) *//** * @n {Number} 正整数, 线程数量 */function Queue (n) {    n = parseInt(n || 1, 10);    return (n && n > 0) ? new Queue.prototype.init(n) : null;}Queue.prototype = {    init: function (n) {        this.threads = [];        this.taskList = [];        while (n--) {            this.threads.push(new this.Thread)        }    },    /**     * @callback {Fucntion} promise对象done时的回调函数,它的返回值必须是一个promise对象     */    push: function (callback) {        if (typeof callback !== ‘function‘) return;        var index = this.indexOfIdle();        if (index != -1) {            this.threads[index].idle(callback)            try { console.log(‘Thread-‘ + (index+1) + ‘ accept the task!‘) } catch (e) {}        }        else {            this.taskList.push(callback);            for (var i = 0, l = this.threads.length; i < l; i++) {                (function(thread, self, id){                    thread.idle(function(){                        if (self.taskList.length > 0) {                            try { console.log(‘Thread-‘ + (id+1) + ‘ accept the task!‘) } catch (e) {}                            var promise = self.taskList.pop()();    // 正确的返回值应该是一个promise对象                            return promise.promise ? promise : thread.promise;                        } else {                            return thread.promise                        }                    })                })(this.threads[i], this, i);            }        }    },    indexOfIdle: function () {        var threads = this.threads,            thread = null,            index = -1;        for (var i = 0, l = threads.length; i < l; i++) {            thread = threads[i];            if (thread.promise.state() === ‘resolved‘) {                index = i;                break;            }        }        return index;    },    Thread: function () {        this.promise = $.Deferred().resolve().promise();        this.idle = function (callback) {            this.promise = this.promise.then(callback)        }    }};Queue.prototype.init.prototype = Queue.prototype;

使用示例:

    var queue = new Queue(3);    // 创建一个具有3个线程的队列
  // task-1 queue.push(
function(){ var defer = $.Deferred(); setTimeout(function(){ defer.resolve() }, 8000); return defer.promise() })
  // task-2 queue.push(
function(){ var defer = $.Deferred(); setTimeout(function(){ defer.resolve() }, 2000); return defer.promise() })
  // task-3 queue.push(
function(){ var defer = $.Deferred(); setTimeout(function(){ defer.resolve() }, 6000); return defer.promise() })
  // task-4 queue.push(
function(){ var defer = $.Deferred(); setTimeout(function(){ defer.resolve() }, 3000); return defer.promise() })
  // task-5 queue.push(
function(){ var defer = $.Deferred(); setTimeout(function(){ defer.resolve() }, 2000); return defer.promise() })
  // task-6 queue.push(
function(){ var defer = $.Deferred(); setTimeout(function(){ defer.resolve() }, 2000); return defer.promise() })

控制台有显示 queue.push的 function (暂且叫它task)  最终是哪个进程处理的

实例化后,队列里的3个线程都是处于空闲状态的
将task-1分配给线程1, 这个任务耗时 8s
将task-2分配给线程2, 这个任务耗时 2s
将task-3分配给线程3, 这个任务耗时 6s

因为当前没有空闲进程,队列内部则将task-4、task-5、task-6添加到等候区

因为task-2耗时2s,进程2最先被解放,然后task-4就被分配到进程2去处理,以此类推,最后控制台显示的进程使用情况是:1、2、3、2、2、3

 

javascript 多线程异步队列