Порядок выполнения Обещаний в Node.js - PullRequest
0 голосов
/ 30 января 2019

Я выполнил следующий код с Node.js v10.15.0

Promise.resolve()
  .then(() => console.log('A'))
  .then(() => console.log('B'))
  .then(() => console.log('C'))

setImmediate(() => console.log('IMMEDIATE'))

Promise.resolve()
  .then(() => console.log('D'))
  .then(() => console.log('E'))
  .then(() => console.log('F'))

Поскольку в полностью заполненных функциях нет асинхронного кода, я ожидал следующий вывод

A
B
C
D
E
F
IMMEDIATE

, но получил...

A
D
B
E
C
F
IMMEDIATE

Насколько я понимаю ситуацию, вызов setImmediate() показывает нам, что ни один вызов console.log() не переносится на следующую итерацию цикла обработки событий.Но почему порядок console.log() вызовов перепутан?

Ответы [ 2 ]

0 голосов
/ 30 января 2019

вызов setImmediate() показывает нам, что никакие вызовы console.log() не откладываются до следующей итерации цикла событий

На самом деле они это делают - помните, что обратные вызовы обещания then являются всегда асинхронный.

Они просто запускаются на другой фазе цикла событий, они ставятся в очередь в разных очередях задач.В частности, для NodeJS, см. Статью https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ для получения подробностей.

Я ожидал следующего вывода

Не предполагайте ничего о независимых цепочках обещаний.Все, что вы можете и должны ожидать, это то, что B идет после A, C идет после B, а в другой цепочке E идет после D и F после E.Они могут произвольно чередоваться 1 - если вы хотите обеспечить порядок, связывайте обещания друг с другом, используя then.

1: спецификация подробно описывает, как очередиЗадачи обещания работают так, чтобы они были согласованы между различными реализациями движка, но эти детали следует считать не относящимися к делу.

0 голосов
/ 30 января 2019

Существует две Promise.resolve()... цепочки обещаний, которые выполняются параллельно.

A
D
B
E
C
F

- это ожидаемый для них порядок.

Чтобы выполнить их последовательно, необходимо:

Promise.resolve()
  .then(() => console.log('A'))
  .then(() => console.log('B'))
  .then(() => console.log('C'))
  .then(() => Promise.resolve()) // no-op
  .then(() => console.log('D'))
  .then(() => console.log('E'))
  .then(() => console.log('F'))
...