前端并发锁

54 阅读1分钟

先贴代码

function asyncLock(num = 2) {
    let length = 0;
    const task = [];

    return function lock(fn){
        return new Promise((r) => {
            if (length < num) {
                length ++;
                return fn().then((data) => {
                    length--;
                    const cur = task.shift();
                    cur && lock(cur);
                    r(data);
                });
            }
            task.push(() => fn().then(d => r(d)));
        })
    }
}

思路:

1、设置配置信息,请求并发数量 num,缓冲区task,当前执行中的任务数量

2、任务执行

  • 如果遇到执行数量小于并发上限,则立即执行,执行结束,则看缓冲区是否有任务,有就拿出来执行,没有就结束
  • 如果执行数量等于并发上限,则将任务放入缓冲区

3、返回每个任务的执行结果,用promise来进行结果的返回

测试代码

function request(val, time) {
    return new Promise((r) => {
        setTimeout(() => {
            r(val)
        }, time)
    })
}

const limit = asyncLock(2);
limit(() => request(1, 1000)).then(d => console.log(d));
limit(() => request(2, 100)).then(d => console.log(d));
limit(() => request(3, 200)).then(d => console.log(d));
limit(() => request(4, 500)).then(d => console.log(d));
limit(() => request(5, 400)).then(d => console.log(d));
limit(() => request(6, 200)).then(d => console.log(d));

// 执行结果: 2 -> 3 -> 4 -> 1 -> 6 -> 5