js实现任务(promise任务)队列

任务队列

队列的特点就是先进先出

先开始的任务执行完后,才能开始执行后续任务
另外任务队列中有任务时是自动执行的。

另外提一点,实现稍微复杂一点功能,全都是闭包!!

设计:new一个队列,返回值是一个function,这个function的入参为为task(类型promise),返回值也是promise

	const queue = new Queue();
	queue(task1).then(data=>console.log(data));
	queue(task2).then(data=>console.log(data));
	//始终都是task1的结果先输出
  1. 实现一个先进先出的普通队列
class Queue {
    
    
	constructor() {
    
    
		let waitingQueue = [];
		let isRunning = false;//记录是否有未完成的任务
		function execute(task, resolve, reject) {
    
    
			task()
				.then((data) => {
    
    
					resolve(data);
				})
				.catch((e) => {
    
    
					reject(e);
				})
				.finally(() => {
    
    
				//等待任务队列中如果有任务,则触发它;否则设置isRunning = false,表示无任务状态
					if (waitingQueue.length) {
    
    
						const next = waitingQueue.shift();
						execute(next.task, next.resolve, next.reject);
					} else {
    
    
						isRunning = false;
					}
				});
		}
		return function(task) {
    
    
			return new Promise((resolve, reject) => {
    
    
				if (isRunning) {
    
    
					waitingQueue.push({
    
     task, resolve, reject });
				} else {
    
    
					isRunning = true;
					execute(task, resolve, reject);
				}
			});
		};
	}
}

const queue = new Queue();
const task1 = () =>
	new Promise((resolve, reject) => {
    
    
		setTimeout(() => {
    
    
			resolve('task1');
		}, 3000);
	});
const task2 = () =>
	new Promise((resolve, reject) => {
    
    
		setTimeout(() => {
    
    
			resolve('task2');
		}, 1000);
	});
const queue = new Queue();
queue(task1).then((data) => console.log(data));
queue(task2).then((data) => console.log(data));
//result
//task1
//task2

2.实现一个有时间间隔,并且超时后会中断任务的任务队列
有几个要点:超时后终止当前任务直接开始下一个任务;delay时间后才会执行下一个任务;如果任务delay了但没超时,则需要立即执行下一个任务

class Queue {
    
    
	constructor({
    
     delay, timeout }) {
    
    
		let timer = null;//当有任务执行时,设置超时检测的定时器
		let waitingQueue = [];//等待任务的队列
		function execute(task, resolve, reject) {
    
    
			let resolved = false;//记录任务是否结束
			let executeNext = false;//记录是否任务结束后,立即执行下一个任务
			task().then((data) => {
    
    
			//任务未超时,则会进入这里
				resolve(data);
				resolved = true;//标记任务完成
				clearTimeout(timer);//清除超时计时器
				timer = null;
				if (executeNext) {
    
    //true代表任务是在delay后完成的,所以直接执行下一个任务
					const next = waitingQueue.shift();
					if (next) {
    
    
						execute(next.task, next.resolve, next.reject);
					}
				}
			});
			timer = setTimeout(() => {
    
    
				reject('超时');//超时直接调用reject
				timer = null;
				const next = waitingQueue.shift();
				if (next) {
    
    //立即执行下一个任务
					execute(next.task, next.resolve, next.reject);
				}
			}, timeout);
			//delay时间后,自动执行下一个任务
			setTimeout(() => {
    
    
				if (resolved) {
    
    //true代表上一个任务已经完成,可以直接执行下一个任务
					const next = waitingQueue.shift();
					if (next) {
    
    
						execute(next.task, next.resolve, next.reject);
					}
				}
				executeNext = true;//标记当前任务完成后,立即执行下个任务(给任务在delay之后完成用)
			}, delay);
		}
		return function(task) {
    
    
			return new Promise((resolve, reject) => {
    
    
				if (!timer) {
    
    //没有任务,则直接执行
					execute(task, resolve, reject);
				} else {
    
    //否则 将任务放入等待队列中
					waitingQueue.push({
    
     task, resolve, reject });
				}
			});
		};
	}
}
const task1 = () =>
	new Promise((resolve, reject) => {
    
    
		setTimeout(() => {
    
    
			resolve('task1');
		}, 3000);
	});
const task2 = () =>
	new Promise((resolve, reject) => {
    
    
		setTimeout(() => {
    
    
			resolve('task2');
		}, 2000);
	});
const task3 = () =>
	new Promise((resolve, reject) => {
    
    
		setTimeout(() => {
    
    
			resolve('task3');
		}, 1000);
	});
const queue = new Queue({
    
    delay:2000,timeout:3000});
queue(task1).then((data) => console.log(data));
queue(task2).then((data) => console.log(data));
queue(task3).then((data) => console.log(data));
//task1 
//task2 
//task3
const task4 = () =>
	new Promise((resolve, reject) => {
    
    
		setTimeout(() => {
    
    
			resolve('task4');
		}, 4000);
	});
queue(task4).then((data) => console.log(data));
queue(task1).then((data) => console.log(data));
queue(task2).then((data) => console.log(data));
queue(task3).then((data) => console.log(data));
//Uncaught (in promise) 超时
//task1
//task2 
//task3

猜你喜欢

转载自blog.csdn.net/XIAOLONGJUANFENG/article/details/113058280