如何确定 es6-promise 构造函数的执行顺序?

How to determine es6-promise constructor execution order?

考虑以下代码。

(async () => {
    const values = {}
    const orders = []
    let promise = 0
    promise = new Promise(async resolve => {
        values[1] = promise
        orders.push(1)
        resolve(1)
        values[2] = promise
        orders.push(2)
        await new Promise(async r => {
            values[3] = await promise
            orders.push(3)
            setTimeout(r, 100)
        })
        values[4] = await promise
        orders.push(4)
        promise = 2
        values[5] = promise
        orders.push(5)
    })
    values[6] = await promise
    orders.push(6)
    await new Promise(resolve => setTimeout(resolve, 100)) // (*). try removing this line, result will change
    values[7] = await promise
    orders.push(7)
    console.log(values, orders)
})()

控制台输出:

{ '1': 0, '2': 0, '3': 0, '4': 1, '5': 2, '6': 1, '7': 1 }
[ 1, 2, 3, 6, 4, 5, 7 ]

我的问题是:

  1. 上面的代码片段中是否有任何语句是未定义的行为?如果不是,我检查结果后对ES6的承诺感到困惑。

  2. 为什么是values[7]1,而不是2?更新:对于 node v10.19.0,它是 1。对于 nodev14.0.0、node-v12.10.0 和浏览器,它是 2。

更新2:用节点v10.19.0重复计算,值20次后[7]为1,一次为2。

  1. 如果我删除 (*) 行,结果将更改为以下内容。为什么删除了 4、5?

    { '1': 0, '2': 0, '3': 0, '6': 1, '7': 1 } [ 1, 2, 3, 6, 7 ]

如果您对这种执行有任何经验法则,请分享。 JS promise代码越写越糊涂

检查更多测试here

如果您对某些事情感到困惑,请尝试将其提炼为只是您感到困惑的情况,而不是所有其他情况,那是说...我的最好猜测我认为您想知道的内容:

  1. 执行器函数(您传递给 new Promise() 的函数)立即被同步调用。
  2. 异步函数在调用时也会立即执行。他们只会在点击第一个 await.
  3. 时暂停
  4. 因此,如果您使用其中没有 await 的异步函数,则 整个异步函数将立即同步执行。
  5. 然而,即使你的异步函数是"synchronous",它也不会立即return。执行是同步的,但解析(处理 .then() listeners)将在下一个 tick 中。