The reason for designing the blocking queue is because we encountered a huge resource list loading problem when doing business. Our business is mainly the loading of media resources. In http 1.0, most browsers supported the maximum number of parallels, which was improved in http 2.0. In theory, HTTP/2.0 can send countless HTTP requests on a TCP connection.
If we load 100 pictures at a time, the network resources will be preempted seriously. If the user's network environment is poor, the resource loading problem is even more serious. Then we can consider controlling the number of parallels, controlling the number of resource loads each time, and controlling the load queue to always be less than 6.
In order to solve this problem, a blocking queue based on promise is designed. The essence is a production and consumption model with a limited queue length. Take the picture as an example:
class Scheduler {
constructor(maxCount = 6) {
this.list = [];
this.count = 0;
this.maxCount = maxCount;
}
// 添加任务队列
addTask(promiseCreator) {
return new Promise((resolve) => {
// 添加的时候通知 队列有东西可以消费
this.list.push(() => {
return promiseCreator().then(res => {
this.count -= 1;
// 一个任务做完下一个任务才开始
this.consume();
resolve(res);
return res;
});
});
this.consume();
});
}
provider = (src) => {
return this.addTask(() => new Promise((resolve, reject) => {
const img = new Image();
img.src = src;
img.onload = function() {
// 图片加载成功
resolve(src);
}
img.onerror = function(err) {
// 图片加载失败
reject(err);
}
}));
};
consume() {
// 最多同时做两个任务
if(this.count < this.maxCount && this.list.length > 0) {
this.count += 1;
const item = this.list.shift();
item && item();
}
}
}
use:
const queue = new Scheduler();
queue.provider('http://xxxxxxxx');
queue.provider('http://xxxxxxxx');
queue.provider('http://xxxxxxxx');
queue.provider('http://xxxxxxxx');
queue.provider('http://xxxxxxxx');
queue.provider('http://xxxxxxxx');
queue.provider('http://xxxxxxxx');
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。