异步回调队列核心是利用微任务机制(如promise链或queuemicrotask)实现fifo串行执行,支持async/promise自动等待、错误处理、暂停/清空等控制能力。

要编写支持异步执行的回调队列,核心是让任务按顺序排队、不阻塞主线程,并能自然处理 Promise 或 async 函数。关键不是手动轮询或 setTimeout 模拟,而是利用 JavaScript 事件循环机制(如 Promise.resolve().then() 或 queueMicrotask)来调度微任务。
设计一个可链式添加的队列结构
回调队列本质是一个待执行函数列表,但需保证“先进先出”且每次只运行一个,前一个完成(尤其是异步完成)后才触发下一个。推荐用 Promise 链式串联实现:
- 内部维护一个“当前执行链”的 Promise,初始为
Promise.resolve() - 每次
push(callback)时,将 callback 包装成.then(() => callback())接到链尾 - callback 可返回普通值、Promise 或 async 函数,链式 then 会自动等待其 resolve
用 queueMicrotask 实现轻量级微任务调度
如果不需要完整 Promise 链(比如只想排队纯异步逻辑、避免嵌套过深),可用 queueMicrotask 手动调度:
- 维护一个数组存储回调函数和参数
- 调用
push(fn, ...args)时,若队列空,则立即queueMicrotask(runNext) -
runNext从队首取任务执行,执行完再调度下一个(如有) - 注意:callback 内部若含异步操作(如 fetch),需自行返回 Promise 并在 resolve 后再调用
runNext,否则会跳过等待
支持暂停、清空与错误透传
生产环境的回调队列常需控制能力:
- 加
pause()/resume():用布尔标记 + 在 runNext 开头检查,暂停时不调度下一任务 - 加
clear():清空待执行队列数组,但正在运行的任务不受影响 - 错误处理:每个 callback 应包裹在
try/catch中;若未捕获,可触发onError回调,或 reject 当前链(影响后续任务)——根据语义选择“失败中断”还是“失败跳过”
一个最小可行示例(基于 Promise 链)
以下代码可直接运行,支持 async 回调、自动串行、无外部依赖:
class AsyncQueue {
constructor() {
this.chain = Promise.resolve();
}
push(fn) {
this.chain = this.chain.then(() => fn()).catch(err => {
console.error('Callback failed:', err);
throw err; // 继续向后抛,保持链断裂行为
});
}
drain() {
return this.chain;
}
}
// 使用:
const q = new AsyncQueue();
q.push(() => console.log('1'));
q.push(() => new Promise(r => setTimeout(() => { console.log('2'); r(); }, 100)));
q.push(async () => { console.log('3'); });
q.drain(); // 输出 1 → 2 → 3,全部异步安全











