Promise 异步任务队列,可动态增加删除队列

336 阅读1分钟

任务队列需求

需求:

  1. 有一个队列数组arr,可以往里面添加、删除任务元素
  2. task队列方式依次执行

比如:arr = [p1, p2, p3, p4]; 必须先执行完p1再执行p2,p3 ... 以此类推

arr可随时添加和删除异步任务

任务队列实现

/**
 * @file 异步队列
 * @desc 传入cache缓存队列,或者动态添加删除cache,trigger方法触发执行队列任务
 */
class QueueTask {
    constructor(cache) {
        this.cache = cache || [];
        this.running = false;
    }

    loop = async (locCache) => {
        for (const element of locCache) {
            try {
                await element.method();

                const delIndex = locCache.findIndex((i) => i.id === element.id);
                if (delIndex !== -1) {
                    locCache.splice(delIndex, 1);
                }
            } catch (error) {
                console.error('error', error);
            }
        }
    };

    trigger = async () => {
        if (this.running === true) {
            return;
        }

        this.running = true;

        try {
            await this.loop(this.cache);
        } catch (error) {
            console.log('error', error);
        } finally {
            this.running = false;
            if (this.cache.length > 0) {
                this.trigger();
            }
        }
    };
}

// how use

let number = 0;
const task = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            number++;
            console.log('number', number);
            resolve();
        }, 1000);
    });
};

const p1 = new QueueTask();
let count = 0;
const interId = setInterval(() => {
    count++;
    if (count >= 10) {
        clearInterval(interId);
    }
    console.log('count:', count);
    p1.cache.push({id: Math.random() + '', method: task});
    p1.trigger();
}, 100);


运行结果:1. 每隔100毫秒输出count的值,2. 每隔一秒钟输出task的异步任务number值

[Running] node "g:\work\node-mongo\utils\QueueTask.js"
count: 1
count: 2
count: 3
count: 4
count: 5
count: 6
count: 7
count: 8
count: 9
count: 10
number 1
number 2
number 3
number 4
number 5
number 6
number 7
number 8
number 9
number 10

[Done] exited with code=0 in 10.906 seconds