基于JS实现任务队列的示例代码

作者:半夏

时间:2026-10-30

浏览:262

本文介绍如何在JavaScript中实现任务队列,以解决异步回调执行顺序混乱的问题。通过维护一个执行标识和队列数组,确保耗时操作按添加顺序依次执行,适用于前端订阅数据变化后的复杂业务逻辑处理。

文章目录

引言

假设存在这样一个应用场景:

  • 前端需要订阅后台数据的变化,一旦数据发生更新,便触发相应的订阅回调;
  • 在回调函数内部,往往涉及一系列耗时操作,例如发起接口请求、发送短信通知或存储历史数据等;
  • 核心要求是上述所有操作必须严格遵循订阅触发的先后顺序执行;

众所周知,回调机制本质上属于异步操作,仅依赖订阅回调本身无法保证其中任务的执行顺序。

针对这一痛点,我们可以引入任务队列机制,将回调函数加入队列后,按序依次执行。

任务队列的概念

顾名思义,任务队列用于存放待处理的任务,且队列中的任务必须严格遵循入队的先后顺序进行执行。

当前一条任务执行结束后,立即启动下一条任务的执行,直至整个任务队列被清空。

任务队列的基本执行流程如下:

  • 向任务队列中添加任务,并检查当前的执行标识状态;
  • 若执行标识为 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任务队列内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章