我在解决另一个承诺时发现了一些有趣的行为:
const someTask = callback => {
new Promise(res => res())
.then(() => callback())
.then(() => console.log("A 1!"))
.then(() => console.log("A 2!"));
};
new Promise(res => someTask(res))
.then(() => console.log("B 1!"))
.then(() => console.log("B 2!"));
此输出:
B 1!
A 1!
B 2!
A 2!
我的想法是,它将:
[至少立即将其中一个链全部入队,以便所有A的.then
回调都将首先运行,然后是B的回调,反之亦然,但是它们似乎来回交替,这令人费解。
在B之前运行A的第一个日志语句,因为它在B之前已解决。
[我知道这可能与实现有关,并且我不应该依赖这里的执行顺序(在我的项目中,我只关心完成时解决A的问题),但这使我很感兴趣为什么会这样。这是带有本地承诺的,而Bluebird会产生相同的输出。
我将避免使用像EnqoeueJob这样的规范术语,以免造成混淆
[只要您.then(() => { ... })
入队微任务。当仅剩下平台代码(“最后”)时,微任务始终运行,并且始终在I / O之前运行。
在您的情况下:
then
总是在新的微滴答声上运行。这意味着您的情况:
then
。这是因为microticks只是在微任务队列的末尾进行调度。因此,交替是“正确”的行为。
这不是实现的定义-尽管这是建立诺言时的巧合和错误。您可以但不应依赖该顺序。