备注:
使用promise对并发请求进行封装,可支持并发请求任务个数及任务优先级。
原理:使用队列的数据结构 ,先进先出的处理请求,如添加任务优先级高的任务,
则会通过数组的shift()方法插入到队列的头部
mock.js文件:
const urls = [
{
info: 'task1',
timeout: 3000,
sort: 1,
},
{
info: 'task2',
timeout: 1000,
sort: 1,
},
{
info: 'task3',
timeout: 2000,
sort: 3,
},
{
info: 'task4',
timeout: 1000,
sort: 2,
},
{
info: 'task5',
timeout: 5000,
sort: 1,
},
{
info: 'task6',
timeout: 3000,
sort: 6,
},
];
const loadingImg = ({ info, timeout }) => {
return new Promise((res, rej) => {
setTimeout(() => {
res(info);
}, timeout);
});
};
module.exports = { urls, loadingImg };
promise封装:
支持并发数量:
const { urls, loadingImg } = require('./mock');
class PromiseQueue {
constructor(options) {
this.maxCurry = options.maxCurry;
this.currentCount = 0;
this.pendingList = [];
}
addTask(fn) {
this.pendingList.push(fn);
this.runTask();
}
runTask() {
if (!this.pendingList.length || this.currentCount === this.maxCurry) return;
this.currentCount++;
const fn = this.pendingList.shift();
const promise = fn();
promise.then(this.restartRunTask.bind(this)).catch(this.restartRunTask.bind(this));
}
restartRunTask() {
this.currentCount--;
this.runTask();
}
}
const queue = new PromiseQueue({ maxCurry: 3 });
urls.forEach((url) => {
queue.addTask(() => loadingImg(url));
});
支持任务优先级:
添加高优任务不会取消当前已经发出的请求,而是放在发出请求后的队列的头部
const { urls, loadingImg } = require('./mock');
class PromiseQueue {
constructor(options) {
this.maxCurry = options.maxCurry;
this.currentCount = 0;
this.pendingList = [];
}
addTask(fn) {
this.pendingList.push(fn);
if (this.pendingList.length > 1) {
this.pendingList = this.pendingList.sort((a, b) => b.sort - a.sort);
}
this.runTask();
}
runTask() {
if (!this.pendingList.length || this.currentCount === this.maxCurry) return;
this.currentCount++;
const { fn } = this.pendingList.shift();
const promise = fn();
promise.then(this.restartRunTask.bind(this)).catch(this.restartRunTask.bind(this));
}
restartRunTask() {
this.currentCount--;
this.runTask();
}
}
const queue = new PromiseQueue({ maxCurry: 3 });
const formatTask = (url) => {
return {
fn: () => loadingImg(url),
sort: url.sort,
};
};
urls.forEach((url) => {
queue.addTask(formatTask(url));
});
queue.addTask(
formatTask({
info: 'high!!!',
timeout: 2000,
sort: 10,
}),
);