JS并发管控

419 阅读1分钟

方法一

//模拟一个ajax请求
const query = function query(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(time)
        }, time)
    })
}

let stack = [
    () => {
        return query(1000);
    },
    () => {
        return query(2000);
    },
    () => {
        return query(3000);
    },
    () => {
        return query(4000);
    },
]

// 并发管控
const asyncPool = function asyncPool(stack, threadCount) {
    if (!Array.isArray(stack)) throw new TypeError(`${stack} is not a Array`);
    if (typeof threadCount == null) threadCount = 2;
    if (typeof threadCount != 'number') throw new TypeError(`${threadCount} is not a number`);

    //把稀疏数组(有empty)变成密集数组 稀疏数组可以用forEach但是不遍历
    let working = new Array(threadCount).fill(null),
        index = 0,
        values = [];
    //开两个工作区  工作区返回Promise  干完了把状态变成fulfilled
    working = working.map(() => {
        return new Promise((resolve, reject) => {
            const next = async function next() {
                //当任务都做完就退出递归
                if (index >= stack.length) {
                    resolve();
                    return;
                }
                try {
                    let result = await stack[index++]();
                    //结果存values
                    values[index-1] = result;
                    
                } catch (error) {
                    values[index-1] = null;
                }
                //一个任务好了继续取下一个任务
                next();
            }
            //引线
            next();
        })
    })
    
    //当working中的两个工作区都是fulfilled就返回values
    return Promise.all(working).then((res) => {
        return values
    });
}

asyncPool(stack, 2).then((res) => {
    console.log(res)
})