如何确保回调函数前一次执行完成后再触发下一次调用?
解决方案:串行化异步回调执行
问题的核心在于,onModelUpdate触发回调时不会等待前一次回调的异步操作完成,导致多次触发的回调并发执行,打破了预期的顺序。要严格保证回调的执行顺序,必须将回调的执行改为串行队列,让每一次回调都等待前一次完全完成后再启动。
实现方式:维护Promise串行链
你可以在注册回调时,自己包装一个串行执行的函数,通过维护一个Promise变量追踪前一次回调的执行状态:
// 初始化一个已完成的Promise,作为串行链的起点 let pendingCallbackPromise: Promise<void> = Promise.resolve(); // 包装原回调,实现串行执行 const serializedCallback = () => { // 将当前回调加入串行链:等待前一次完成后再执行 pendingCallbackPromise = pendingCallbackPromise .then(async () => { await callbackFn(); }) .catch(error => { // 捕获错误,避免后续回调因前一次失败而被阻塞 console.error("回调执行失败:", error); }); }; // 注册包装后的串行回调 onModelUpdate(serializedCallback);
代码解释
pendingCallbackPromise:始终保存上一次回调的Promise实例,初始为已完成状态,确保第一次回调可以立即执行。- 串行链逻辑:每次触发回调时,都会把当前的
callbackFn加到前一次Promise的then方法中,只有前一次回调的所有异步操作(包括doB内部的doA)完全完成,当前回调才会开始执行。 - 错误处理:添加
catch捕获执行错误,避免某一次回调失败导致整个串行链中断,后续回调无法执行。
可选方案:修改onModelUpdate内部实现(若有权限)
如果你能修改模型的onModelUpdate方法,可以把串行逻辑内置进去,让所有注册的回调都自动串行执行:
class YourModel { // 内部维护串行链的Promise private pendingUpdatePromise: Promise<void> = Promise.resolve(); onModelUpdate(callbackFn: () => Promise<void>): void { this.on(modelUpdateEvent, () => { this.pendingUpdatePromise = this.pendingUpdatePromise .then(async () => { await callbackFn(); }) .catch(error => { console.error("模型更新回调执行失败:", error); }); }); } }
这样无论注册多少个回调(或同一个回调多次触发),都会严格按照触发顺序串行执行,前一次完成后再执行下一次。
内容的提问来源于stack exchange,提问作者Advaita11
相关产品推荐
相关产品推荐

