考虑以下代码。
(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 ]
我的问题是:
在上面的片段中是否有任何语句是未定义的行为?如果没有,在检查结果后,我对ES6承诺感到困惑。
为什么是 values[7]
1
,不 2
? 更新:节点v10.19.0为1,节点v14.0.0、节点v12.10.0和浏览器为2。
更新2:用节点v10.19.0重复评估,20次后值[7]为1,一次为2。
如果我把(*)行去掉,结果就会变成下面的样子。为什么去掉4、5?
{ '1': 0, '2': 0, '3': 0, '6': 1, '7': 1 }[ 1, 2, 3, 6, 7 ]
如果你对这种执行方式有什么经验法则,请分享。我越写JS承诺代码,越是迷茫。
查看更多测试 此处.
如果你有什么不明白的地方,可以试着把它提炼为以下内容 只是 你所困惑的情况,而不是其他所有的情况,说到这里......我想你想知道的是我最好的猜测。
new Promise()
)会立即被调用,同步进行。await
.await
中,整个async函数将立即被同步执行。.then() listeners
)将在下一个tick)。