何泽弘

何泽弘的博客

这是一个中二半吊子码农分享学习经验和生活的网站...

实现javascript中的队列结构


1、队列的定义

  • 队列(Queue):也是运算受限的线性表。是一种先进先出(First In First Out ,简称FIFO)的线性表。只允许队首(front)进行插入,而在队尾(rear)进行删除。
  • 队首(front):允许进行删除的一端称为队首。
  • 队尾(rear):允许进行插入的一端称为队尾
  • 空队列:队列中没有元素时称为空队列。

例如上洗手间,假设有很很多人要上洗手间,但是洗手间位置不多,这个时候就要排队上厕所啦,谁先来的谁就可以使用洗手间(没有插队的情况下),使用完了, 后面的人跟上,然后就是不断的有人排队(进队列),不断的有人上完洗手间出来(出队列),没人出来后面的人就要憋着这样的一个队列模式。直到没人要上洗手间了,洗手间就空出来了(空队列)。

登录页

2、队列任务

假设我们有100项任务要处理,一个人只能同时处理一项任务,处理完了才可以处理下一个任务,现在我们有5个人,这样子我们就形成了一个并发为5的一个任务队列。就是5个人不间断同时工作,不管任务执行时间,处理完了接着处理下一个任务,直到所有100个项目处理完成。

3、代码实现

3.1、创建队列的类对象实现

var Queue = (function () {
    function Queue (worker, concurrency) {
        this.tasks = [];
        this.worker = typeof worker === 'function' ? worker : null;
        this.concurrencyMax = typeof concurrency === 'number' && concurrency > 0 ? concurrency : 1;
        this.concurrencyCut = 0;
        this.drain = null;
    }
    Queue.prototype._start = function () {
        if (this.tasks.length === 0 || this.concurrencyCut >= this.concurrencyMax) {
            return ;
        }
        var taskData = this.tasks.shift();
        this.concurrencyCut += 1;
        this.worker && this.worker(taskData.task, this._next.bind({ taskData: taskData, self: this }));
    };
    Queue.prototype._next = function () {
        var self = this.self;
        var taskData = this.taskData;
        taskData.callback && taskData.callback.apply(this, arguments);
        self.concurrencyCut -= 1;
        if ( self.tasks.length > 0 ) { return self._start(); }
        if ( self.concurrencyCut === 0 ) { return self.drain && self.drain(); }
    };
    Queue.prototype.push = function (task, callback) {
        this.tasks.push({ task: task, callback: callback });
        if ( this.concurrencyCut < this.concurrencyMax ) { return this._start(); }
    };
    return Queue;
})();

3.2、使用说明

/** 创建一个并发为10的一个任务队列 */
var queue = new Queue(function (task, next) {
    // task: 当前任务
    // next: 当前任务处理完了,执行next(arguments);进行回调
    console.log('正在处理' + task.name + '任务');
    return next();
}, 10);

// 队列为空的时候调用的function
queue.drain = function() {
    console.log('所有任务都执行完了');
};

// 将一些任务添加到队列中
queue.push({name: 'foo'}, function() {
    console.log('foo任务完成了');
});
queue.push({name: 'bar'}, function () {
    console.log('bar任务完成了');
});

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请狠狠点击下面的