在下一次调用之前完成回调的上一次执行

Complete previous execution of the callback before its next invocation

提问人:Advaita11 提问时间:6/25/2023 最后编辑:Advaita11 更新时间:6/25/2023 访问量:68

问:

我有一个回调函数,写得像这样。

callbackFn = (): Promise<void> => {
    if ('condition 1') {
        await doA();
    }
    else {
        await doB();
    }
}
doB = (): Promise<void> => {
// Do something 
// other await calls
    await doA();
}
doA = (): Promise<void> => {
    // Do something
}

在客户端,此 callbackFn 已注册到 model,以便可以在模型更新时调用它。

    onModelUpdate(callbackFn: () => void): void {
        this.on(modelUpdateEvent, callbackFn);
    }

在从模型调用回调的第一个实例期间,将执行 else 流。而下一次回调调用会加速 if 部分。

但是,在执行过程中,源自 if 部分的 doA() 首先执行,而不是源自 doB() 的 doA()。如何确保我的第一次回调执行在第二次之前完成?

我希望保留回调执行的顺序,但我不确定如何做到这一点。

JavaScript TypeScript 回调

评论

2赞 Unmitigated 6/25/2023
请提供一个最小的可重现示例,可以直接运行以查看问题。首先,你的定义是无效的语法。callbackFn
0赞 Advaita11 6/25/2023
我试图添加更多细节来澄清,但是我现在无法更好地解释它。请原谅我,并提前致谢。
2赞 Titus 6/25/2023
创建一个队列,并在其中将任务添加到该队列中,而不是直接执行它们。callbackFn
0赞 pilchard 6/25/2023
你的回调或命名函数都不是异步的,所以 await 没有效果(甚至不应该在没有错误的情况下使用)
0赞 Community 6/25/2023
请提供足够的代码,以便其他人可以更好地理解或重现问题。

答:

-2赞 jdforsythe 6/25/2023 #1

您应该研究 JS 中的事件循环(请参阅此处的 Node.JS 事件循环解释)。

重要的是,当您运行包含回调的代码时(使用 .then() 启动 Promise、使用计时器或传递回调(如模型更新事件),该回调将被安排在将来的某个时间运行。例如,当方法执行时,它会在内存中创建一个回调,该回调将计划在事件触发时执行。onModelUpdate()

该计划执行发生在事件循环生命周期中的特定时间,具体取决于回调类型等因素。在 Node.JS 中,your 将被安排在“待处理回调”队列中执行,该队列与“计时器”和“关闭回调”队列分开,并将在事件循环到达周期的该部分并且它前面的队列已经耗尽时执行。callbackFn()

如果该回调调用 await(开始执行包含回调的 Promise,就像您的函数一样),则在 Promise 解析后,将安排一个单独的回调。onModelUpdate()

与此同时,事件循环可能已经循环了很多次,其他代码正在执行,安排许多其他回调在不同的队列中执行。你不能指望 Promise 在执行其他操作后解决,因为它是在第一个操作之后启动的 - 如果第一个操作有几个 execute+schedule 回调周期要经历,则尤其不会发生这种情况。

如果需要按特定顺序执行它们,则无法在不增加复杂性的情况下异步触发它们。您可能需要重新构建应用程序。

如果一个进程确实依赖于另一个进程首先执行,则必须同步编写它们,或者您必须通过链接回调、链接 Promise、使用单独的队列、消息队列 + 轮询、“互斥锁”或其他方式来按顺序专门调度它们。