基于JS实现任务队列的示例代码
作者:编程三昧
顾名思义,任务队列就是存放任务的队列,队列中的任务都严格按照进入队列的先后顺序执行,所以下面我们就来看看如何基于JS实现任务队列吧
引言
假设有这么一个场景:
- 前端订阅后台数据的变化,如果发生变化,则触发订阅回调;
- 回调函数中,会执行一些耗时操作,如:请求接口,发送短信,存历史数据等;
- 要求以上所有的操作都必须按照订阅触发的顺序执行;
我们都知道,回调本身就是一种异步操作,我们仅仅依靠订阅回调无法保证回调中任务执行顺序的。
为了解决这个问题,我们可以使用任务队列,将回调函数添加到任务队列中,然后按照顺序依次执行。
任务队列的概念
顾名思义,任务队列就是存放任务的队列,队列中的任务都严格按照进入队列的先后顺序执行。
在前一条任务执行完毕后,立即执行下一条任务,直到任务队列清空。
任务队列的基本执行流程如下:
- 给任务队列添加任务,并判断执行标识;
- 如果执行标识为 false,则将任务从队列中独立出来;
- 开始执行任务,将执行标识置为 true;
- 执行完毕后,判断队列是否为空,如果不为空,则继续执行下一条任务;
- 直至任务队列清空。
任务队列一直在循环进行如上步骤。
任务队列的 JS 实现
我们选择使用数组来维护队列的执行顺序,按照“先进先出“的原则,依次从数组的第一个元素开始往后执行。
简易代码实现如下:
/** @format */ class TaskQueue { constructor() { this.queue = []; this.isRunning = false; } /** * @description 将任务添加至队列 * @param {Promise} queueFunction * @returns {undefined} */ addQueue(queueFunction) { this.queue.push(queueFunction); if (!this.isRunning) { this.processQueue(); } } /** * @description 如果队列不为空,则开始处理队列中的任务,本次任务执行完毕后,立刻开始下一条任务的执行 * @param {} */ processQueue() { if (this.queue.length > 0) { this.isRunning = true; const queueFunction = this.queue.shift(); queueFunction().finally(() => { this.processQueue(); }); } else { this.isRunning = false; } } }
测试
我们使用如下代码来测试上述实现:
let taskQueue = new TaskQueue(); let f1 = function (name) { return new Promise((resolve) => { setTimeout(() => { console.log(`我是 f1`, name); resolve(); }, 3000); }); }; let f11 = async function () { await f1(" 任务 1"); }; let f2 = function (name) { return new Promise((resolve) => { setTimeout(() => { console.log(`我是 f2`, name); resolve(); }, 2000); }); }; let f22 = async function () { await f2(" 任务 2"); }; let f3 = function (name) { return new Promise((resolve) => { setTimeout(() => { console.log(`我是 f3`, name); resolve(); }, 1000); }); }; let f33 = async function () { await f3(" 任务 3"); }; taskQueue.addQueue(f11); taskQueue.addQueue(f22); taskQueue.addQueue(f33); // 依次输出: // 我是 f1 任务 1 // 我是 f2 任务 2 // 我是 f3 任务 3
如果不使用任务队列,上面的测试应该是按照 f1 -> f2 -> f3 的顺序执行,但是使用了任务队列之后,f1 -> f2 -> f3 的顺序执行被改变了,这是因为任务队列的执行顺序是按照添加的顺序来的,而不是按照执行顺序来的。
总结
任务队列的实现非常简单,但是使用起来却非常灵活,我们可以根据实际需求来决定任务队列的执行顺序,也可以根据实际需求来决定任务队列的执行时机。
到此这篇关于基于JS实现任务队列的示例代码的文章就介绍到这了,更多相关JS任务队列内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!