javascript 多線程非同步隊列

來源:互聯網
上載者:User

首先,你得知道 jQuery.Deferred 的大致用法,然後,我們進入正題吧:

庫代碼:

/*! * 多線程非同步隊列 * 依賴 jQuery 1.8+ (如果你用的是 1.6或1.7, 只要將源碼中的 then方法替換為pipe方法 即可) *//** * @n {Number} 正整數, 線程數量 */function Queue (n) {    n = parseInt(n  1, 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.pop()();    // 正確的傳回值應該是一個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 cqueue.push(function(){    return $.ajax();    // jq 的ajax返回的正是 promise對象})// request bqueue.push(function(){    return $.ajax();})// request aqueue.push(function(){    return $.ajax();})

 queue.push(callback)   callback必須返回一個promise對象



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.