备注:
使用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,}),);
