Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
665 views
in Technique[技术] by (71.8m points)

node.js - JS Promise's inconsistent execution order between nodejs versions

I am reading the article about nodejs promise here.

Then I try running the following sample code (from the article)

const p = Promise.resolve();

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

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

The results are inconsistent between node versions. With node v10 staying out of all other versions.

I am using a mac.

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

The article says that v10 introduces a breaking change to correct the execution order and the behavior of v8 is a bug. However, when I tested with v12 and v14, they give the same result as v8.

Could anyone explain to me why this happens?

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is due to this change in the specs which now allows shortcircuiting await promiseInstance to not wrap promiseInstance into a new Promise internally and hence saving two ticks (one for waiting for promiseInstance and one to wake up the async function).

Here is a detailed article from the authors of the specs' patch, which also occur to be v8 devs. In there, they explain how that behavior was actually already in nodejs v.8 but was against the specs by then, i.e a bug, that they fixed in v.10, before this patch makes it the official way of doing, and it gets implemented in v8 engine directly.

So if you wish the inlined version that should have happened before this patch is

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'));

while the patch makes it

const p = Promise.resolve();

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

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...