如何实现无返回值异步方法的链式顺序执行?
实现无感知链式调用的顺序异步API
这需求太常见了!要让用户不用管Promise,直接链式调用异步方法还能保证顺序,核心就是在API类内部维护一个Promise任务队列,让每个方法都等前一个异步操作完成后再执行,同时每次调用都返回实例本身,保持链式的连贯性。
完整实现代码
class Api { constructor() { // 初始化一个已完成的Promise作为队列起点,确保第一个任务能直接执行 this.promiseQueue = Promise.resolve(); } // 内部工具方法:把异步任务加入队列 #enqueue(task) { // 把新任务串到队列末尾,更新队列的Promise引用 this.promiseQueue = this.promiseQueue .then(() => task()) .catch(err => { // 可选:捕获错误避免队列中断,这里做个日志输出 console.error('异步任务执行出错:', err); }); // 返回实例本身,支持链式调用 return this; } // 公开的异步方法1 doAsync() { return this.#enqueue(() => { return new Promise(resolve => { setTimeout(() => { console.log('doAsync 执行完毕'); resolve(); }, 1000); }); }); } // 公开的异步方法2 doAnotherAsync() { return this.#enqueue(() => { return new Promise(resolve => { setTimeout(() => { console.log('doAnotherAsync 执行完毕'); resolve(); }, 800); }); }); } // 公开的异步方法3 doAThirdAsync() { return this.#enqueue(() => { return new Promise(resolve => { setTimeout(() => { console.log('doAThirdAsync 执行完毕'); resolve(); }, 500); }); }); } // 可选:给用户提供等待所有任务完成的方法 wait() { return this.promiseQueue; } }
怎么用?完全符合你的需求!
const api = new Api(); // 直接链式调用,不用加await或者.then api.doAsync().doAnotherAsync().doAThirdAsync(); // 要是偶尔需要等所有任务都做完,还能用wait方法 api.doAsync().doAnotherAsync().wait().then(() => { console.log('所有异步任务都执行完啦!'); });
执行后控制台的输出顺序会严格按照调用顺序来:
doAsync 执行完毕(1秒后)
doAnotherAsync 执行完毕(再过0.8秒)
doAThirdAsync 执行完毕(再过0.5秒)
关键逻辑拆解
- 队列初始化:构造函数里用
Promise.resolve()创建一个已完成的Promise,作为队列的“起点”,这样第一个异步任务不需要等待就能直接执行。 - 任务入队:
#enqueue是核心私有方法,它接收一个返回Promise的任务函数,把这个任务通过.then()串到队列的末尾,同时更新队列的Promise引用。这样每个新任务都会自动等待前一个任务完成。 - 链式调用支持:每个公开方法调用
#enqueue后都会返回this(也就是API实例),所以用户可以一直链式写下去,完全不用关心Promise的存在。 - 错误处理:加了
catch块捕获单个任务的错误,避免某个任务失败导致整个队列中断。如果需要失败后终止队列,直接去掉catch或者在catch里重新抛出错误就行。
内容的提问来源于stack exchange,提问作者richbai90
相关产品推荐
相关产品推荐

