前言:p-limit源码阅读计划 请查看若川视野 x 源码共读
- 入参
concurrency接受一个大于等于1的number类型的值,如果不合法会抛出异常
- 创建一个队列
const queue = new Queue();创建队列使用了yocto-queue这个库
activeCount标记队列中还有多少正在执行的函数个数next函数
执行的是队列中的出站函数
const next = () => {
activeCount--;
if (queue.size > 0) {
queue.dequeue()();
}
};
run函数
依次往队列中增加函数并执行
const run = async (fn, resolve, args) => {
activeCount++;
const result = (async () => fn(...args))();
resolve(result);
try {
await result;
} catch {}
next();
};
- enqueue 函数
通过
yocto-queue管理队列里面的函数并绑定上下文
const enqueue = (fn, resolve, args) => {
queue.enqueue(run.bind(undefined, fn, resolve, args));
(async () => {
// This function needs to wait until the next microtask before comparing
// `activeCount` to `concurrency`, because `activeCount` is updated asynchronously
// when the run function is dequeued and called. The comparison in the if-statement
// needs to happen asynchronously as well to get an up-to-date value for `activeCount`.
await Promise.resolve();
if (activeCount < concurrency && queue.size > 0) {
queue.dequeue()();
}
})();
};
- 返回一个Promise函数的返回值
构建了一个Promise的返回函数,并附加了三个属性:
activeCount标记队列中还有多少正在执行的函数个数pendingCount队列等待执行的函数有多少个clearQueue清空队列
const generator = (fn, ...args) => new Promise(resolve => {
enqueue(fn, resolve, args);
});
Object.defineProperties(generator, {
activeCount: {
get: () => activeCount,
},
pendingCount: {
get: () => queue.size,
},
clearQueue: {
value: () => {
queue.clear();
},
},
});