JS Несогласованный порядок выполнения обещания между nodejs версиями - PullRequest
4 голосов
/ 27 мая 2020

Я читаю статью о nodejs обещании здесь .

Затем я пытаюсь запустить следующий пример кода (из статьи)

const p = Promise.resolve();

(async () => {
  await p; console.log('after:await');
})();

p.then(() => console.log('tick:a'))
 .then(() => console.log('tick:b'));

результаты несовместимы между версиями узла. С узлом v10, оставшимся вне всех других версий.

Я использую ma c.

v8.17.0
after:await
tick:a
tick:b

v10.20.1
tick:a
tick:b
after:await

v12.17.0
after:await
tick:a
tick:b

v14.3.0
after:await
tick:a
tick:b

В статье говорится, что v10 вводит критическое изменение для исправления порядка выполнения и поведение v8 - это ошибка. Однако, когда я тестировал версии v12 и v14, они дали тот же результат, что и v8.

Может ли кто-нибудь объяснить мне, почему это происходит?

введите описание изображения здесь

1 Ответ

2 голосов
/ 07 июля 2020

Это связано с этим изменением в спецификациях , которое теперь позволяет короткому замыканию await promiseInstance не переносить promiseInstance в новое Promise внутри и, следовательно, сохранять два тика (один для ждем promiseInstance и один пробудит функцию asyn c).

Вот подробная статья от авторов патча спецификаций, которые также являются разработчиками v8. Там они объясняют, как такое поведение на самом деле уже было в nodejs v.8, но к тому времени противоречило спецификациям, то есть ошибка, которую они исправили в версии 10, до того, как этот патч сделает это официальным способом, и он реализуется непосредственно в движке v8.

Итак, если вы используете sh встроенная версия, которая должна была произойти до этого патча, будет

const p = Promise.resolve();

new Promise((res) => p.then(res)) // wait for p to resolve
  .then((res) => Promise.resolve(res)) // wake up the function
  .then((res) => console.log('after:await'));

p.then(() => console.log('tick:a'))
 .then(() => console.log('tick:b'));

, а патч сделает это

const p = Promise.resolve();

p.then(() => console.log('after:await'));

p.then(() => console.log('tick:a'))
 .then(() => console.log('tick:b'));
...