zoukankan      html  css  js  c++  java
  • javascript 多线程异步队列

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

    库代码:

    /*!
     * 多线程异步队列
     * 依赖 jQuery 1.8+ (如果你用的是 1.6或1.7, 只要将源码中的 then方法替换为pipe方法 即可)
     */
    
    /**
     * @n {Number} 正整数, 线程数量
     */
    function Queue (n) {
        n = parseInt(n, 10);
        return new Queue.prototype.init( (n && n > 0) ? n : 1 )
    }
    
    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.shift()();    // 正确的返回值应该是一个promise对象
                                return promise.promise ? promise : $.Deferred().resolve().promise();
                            } else {
                                return $.Deferred().resolve().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对象



  • 相关阅读:
    Java 中位移运算符 >>,>>>,<<
    HashMap 源码解读
    CentOS 配置防火墙操作实例(启、停、开、闭端口)
    CentOS 配置防火墙操作实例(启、停、开、闭端口)
    js实现页面重新加载
    js实现页面重新加载
    关于Ajax的技术组成与核心原理
    关于Ajax的技术组成与核心原理
    PHP水印制作
    PHP水印制作
  • 原文地址:https://www.cnblogs.com/MyNameIsJim/p/javascrip_multithread_async_queue.html
Copyright © 2011-2022 走看看