javascript可通过闭包封装带超时控制的异步任务队列:用数组存任务、promise链串行执行、promise.race实现单任务超时,暴露push添加任务和start启动执行。

JavaScript 中可以通过闭包封装一个带超时控制的异步任务队列,核心是:用数组维护待执行任务、用 Promise 链串行执行、每个任务包裹在 Promise.race 中与定时器竞争,超时则拒绝。
基本结构:闭包封装状态与方法
用立即执行函数创建私有作用域,保存队列、是否运行中、默认超时时间等变量,暴露 push 和 start 方法:
const createTimeoutQueue = (defaultTimeout = 5000) => {
const queue = [];
let isRunning = false;
const push = (taskFn, timeout = defaultTimeout) => {
queue.push({ taskFn, timeout });
};
const start = () => {
if (isRunning || queue.length === 0) return;
isRunning = true;
processNext();
};
const processNext = () => {
if (queue.length === 0) {
isRunning = false;
return;
}
const { taskFn, timeout } = queue.shift();
Promise.race([
new Promise((resolve, reject) => {
taskFn().then(resolve).catch(reject);
}),
new Promise((_, reject) => {
setTimeout(() => reject(new Error(`Task timeout after ${timeout}ms`)), timeout);
})
])
.then(result => {
console.log('✅ Task succeeded:', result);
processNext();
})
.catch(err => {
console.error('❌ Task failed:', err.message);
processNext();
});
};
return { push, start };
};
使用示例:添加带超时的异步任务
创建队列实例后,用 push 添加返回 Promise 的函数(如 fetch、setTimeout 包装的异步操作),再调用 start 启动:
const queue = createTimeoutQueue(3000); // 默认超时 3s
queue.push(() => fetch('/api/data').then(r => r.json()), 2000); // 指定 2s 超时
queue.push(() => new Promise(res => setTimeout(() => res('done'), 1000)));
queue.push(() => new Promise((_, rej) => setTimeout(() => rej('simulated error'), 500)));
queue.start(); // 开始串行执行
每个任务独立超时,失败不影响后续任务继续执行(可按需调整错误策略)。
增强点:支持取消、暂停、优先级或并发数
可在闭包内扩展能力,例如:
-
取消队列:添加
clear方法清空未执行任务 -
暂停/恢复:用布尔标志控制
processNext是否递归调用 -
并发限制:不一次性全执行,改用
while+ 计数器控制同时最多 N 个任务 -
任务标识与回调:给
push增加onSuccess/onError参数,透传结果
注意点:避免常见陷阱
实际使用中需留意:
- 任务函数本身必须返回 Promise;若返回非 Promise,需用
Promise.resolve(taskFn())包裹 -
Promise.race中的定时器不会自动清除,但任务完成后无影响;如需严格清理,可用AbortController配合(适用于 fetch) - 错误未捕获会中断当前任务链,但因外层有
catch,不影响队列整体流程 - 闭包确保
queue、isRunning不被外部篡改,保障状态隔离
这种实现轻量、可控、易扩展,适合处理需顺序执行且对响应时间敏感的异步场景,比如批量接口调用、设备指令下发、重试逻辑前置等。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











