且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

附加不同承诺链时 Javascript 承诺的执行顺序

更新时间:2023-02-06 21:04:02

首先,当你这样做时:

promise.then(...).then(...)

这将一个 .then() 处理程序附加到 promise 和第二个 .then() 附加到一个新的承诺,第一个.then() 返回.

That attaches one .then() handler to promise and the second .then() is attached to a new promise that the first .then() returns.

因此,当 promise 解析时,第一个 .then() 被安排在事件循环的下一个滴答上触发.然后,只有当第一个 .then() 完成时,它才会安排第二个 .then() 在事件循环的下一个滴答上触发(它不会继续运行)事件循环的这个滴答声).

So, when promise resolves, the first .then() is scheduled to fire on the next tick of the event loop. Then, only when the first .then() finishes, it schedules the second .then() to fire on the next tick of the event loop (it does not run on this tick of the event loop).

当你这样做时:

promise
  .then(() => console.log('2'))
  .then(() => console.log('3'));

promise
  .then(() => console.log('4'))
  .then(() => console.log('5'));

然后,当 promise 解析时,then(2)then(4) 是仅有的两个 .then() 这段代码中直接附加到 promise 的处理程序被安排在事件循环的下一个滴答上运行.在下一个滴答声中,首先 then(2) 运行,然后 then(4) 运行.由于它们都附加到同一个 Promise,因此它们以 FIFO 方式运行,第一个被附加的首先运行.当 then(2) 运行时,它安排 then(3) 在事件循环的下一个滴答上运行,当 then(4)运行,它安排 then(5) 在事件循环的下一个滴答上运行.

And, then when promise resolves, then(2) and then(4) which are the only two .then() handlers in this piece of code directly attached to promise are scheduled to run on the next tick of the event loop. Upon that next tick, first then(2) runs and then then(4) runs. Since they were both attached to the same promise, they run in a FIFO manner, the first one to be attached runs first. When then(2) runs, it schedules then(3) to run on the next tick of the event loop and when then(4) runs, it schedules then(5) to run on the next tick of the event loop.

因此,在 then(2)then(4) 都运行后,在事件循环的下一个滴答声中,您将看到 then(3)then(5) 运行,这解释了您在控制台中看到的排序:

So, after both then(2) and then(4) have run, upon the next tick of the event loop, you will see then(3) and then(5) run and that explains the sequencing you see in the console of:

1
2
4
3
5

我想您不会对 then(1) 首先运行感到惊讶,所以我没有将其添加到解释中.


I presume you're not surprised that then(1) runs first so I didn't add that to the explanation.

为了将它们注册到主要承诺,如何不执行此操作?

How is this not executed in order they are being registered to the main promise?

直接附加到 promise 的三个 .then() 处理程序确实按照它们附加的顺序运行.显然让您感到困惑的是,链接的 .then() 处理程序没有直接附加到 promise,而是附加到 promise.then() 的新承诺代码>返回.

The three .then() handlers attached directly to promise do run in the order they were attached. What is apparently confusing you is that the chained .then() handlers are not attached directly to promise, but to new promises that promise.then() returns.

.then() 返回一个新的 promise,因为它可能不会立即解析.如果 .then() 内部的回调本身返回一个承诺,那么 .then() 返回的承诺不会立即解决.它必须等到 .then() 回调返回的承诺也解决.

.then() returns a new promise because it may not resolve immediately. If the callback inside of .then() itself returns a promise, then the promise that .then() returns does not immediately resolved. It has to wait until the promise that the .then() callback returned also resolves.

在我看来,然后 API 将所有回调添加到一个数组或类似的东西中,从 1 到 5,一旦 res 被调用,它就会开始从数组中一一调用回调(FIFO),这应该会产生日志 1 2 34 5 不是 1 2 4 3 5.

In my mind, then API adds all the callbacks to an array or something like that, from 1 to 5 and once res is called it starts calling callbacks from the array one by one (FIFO) which should produces logs 1 2 3 4 5 not 1 2 4 3 5.

好吧:1、2 和 4 确实被添加到 promise 对象的同一个 .then() 处理程序回调数组中.但是,如上所述,3 和 5 是在由 .then() 创建的单独承诺上,它们链接到.因此,1、2 和 4 执行 FIFO.但是 3 和 5 被延迟到事件循环的后续滴答.

Well: 1, 2 and 4 are indeed added to the same array of .then() handler callbacks for the promise object. But, as explained above, 3 and 5 are on separate promises that were created by the .then() they are chained to. So, 1, 2 and 4 are executed FIFO. But 3 and 5 are delayed to a subsequent tick of the event loop.