javascript 多线程异步队列

页面导航:首页 > 网络编程 > JavaScript > javascript 多线程异步队列

javascript 多线程异步队列

来源: 作者: 时间:2016-02-20 09:49 【

首先,你得知道 jQuery Deferred 的大致用法,然后,我们进入正题吧:库代码:复制代码 *!* 多线程异步队列* 依赖 jQuery 1 8+ (如果你用的是 1 6或1 7, 只要将源码中的 then方法替换为pipe方法
首先,你得知道 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
 
 
 
这个库的使用场景是这样的
1、如本人最近做的项目:
主播在做直播,很多观众会给主播送礼物,这些礼物都是有js动画特效的,页面中最多可以同时显示三个礼物特效
 
2、相互依赖的异步请求
a请求依赖b请求,b请求依赖c请求,c请求依赖。。。
这个需求我们就可以使用这个库这样实现:
 
复制代码
var queue = new Queue(1);
 
// request c
queue.push(function(){
    return $.ajax();    // jq 的ajax返回的正是 promise对象
})
 
// request b
queue.push(function(){
    return $.ajax();
})
 
// request a
queue.push(function(){
    return $.ajax();
})
复制代码
 queue.push(callback)   callback必须返回一个promise对象
 
Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<