核心是用闭包封装并发状态实现隔离可控调度:内部维护running、queue、max等私有变量,任务按余量执行或入队,完成自动触发下一任务,多实例互不影响。

核心在于用闭包封装并发状态(如当前运行数、待执行队列、最大限制),让每次异步迭代都共享同一套受控上下文,又彼此隔离不干扰。
用闭包保存并发控制的私有状态
把 runningCount、pendingQueue 和 maxConcurrency 定义在工厂函数内部,外部无法直接修改,但所有任务调度逻辑都能安全读写它们。
- 每次调用加载函数时,先检查
runningCount ;满足就立即执行,否则推入 <code>pendingQueue - 每个任务完成(无论成功或失败)后,
runningCount--,并从队列取一个新任务启动 - 多个实例调用
createImageLoader(3)会各自拥有独立状态,互不影响
结合 Promise 链实现动态调度
闭包内维护一个始终指向“下一个可插入位置”的 currentChain,新任务总是通过 .then() 接入链尾,再由内部计数器决定是立刻发还是排队等。
- 定义
let currentChain = Promise.resolve() - 每次
loadImage(url)返回currentChain = currentChain.then(() => loadImageWithLimit(url)) -
loadImageWithLimit内部判断并发余量:够就执行,不够就返回new Promise(resolve => pendingQueue.push(resolve)),由完成回调统一触发出队
支持取消与错误透传的结构设计
在闭包中维护一个 WeakMap 或 Map,以任务标识(如 url 或 id)为键,AbortController 实例为值。
- 暴露
cancel(url)方法,闭包内查表并调用abort() - 图片加载若用
fetch + createObjectURL,可真正支持取消;纯img.src则靠标记+忽略后续回调模拟 - 错误统一交由闭包内注册的
onError处理,支持外部传入,也提供默认 fallback
一个轻量可用的实例骨架
以下是一个基于闭包的最小可行异步图片加载器,支持 3 路并发、自动排队、完成回调与错误聚合:
const createImageLoader = (max = 3) => {let running = 0;
const queue = [];
const results = new Map();
const runNext = () => {
if (queue.length === 0 || running >= max) return;
running++;
const task = queue.shift();
task().finally(() => {
running--;
runNext();
});
};
return (url, options = {}) => new Promise((resolve, reject) => {
const task = () => fetch(url, options)
.then(r => r.blob())
.then(blob => URL.createObjectURL(blob))
.then(src => { results.set(url, { src }); resolve(src); })
.catch(err => { results.set(url, { error: err }); reject(err); });
if (running task();
} else {
queue.push(task);
runNext();
}
});
};
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











