在外部范围内的变量上使用await inline

pan*_*ter 3 javascript scope async-await

(async function iife () {
  const numbers = [1, 2, 3, 4]
  let count = 0
  async function returnNumberAsync (number) {
    return new Promise(resolve => {
      setTimeout(() => resolve(number), 0)
    })
  }
  await Promise.all(numbers.map(async number => {
    count += await returnNumberAsync(number)
  }))
  console.log(count)
})()
Run Code Online (Sandbox Code Playgroud)

此代码段记录4到控制台,这完全超出了我的范围。一旦将内部的承诺值分配map给它自己的局部变量…

const result = await returnNumberAsync(number)
count += result;
Run Code Online (Sandbox Code Playgroud)

…它的记录10与我期望的一样。当我count += await …??

Cer*_*nce 6

当你这样做count += await <expression>,初始值count将被添加到决心值保存之前await部分得到解决。所以

count += await returnNumberAsync(number)
Run Code Online (Sandbox Code Playgroud)

就好像

count = count + await returnNumberAsync(number)
Run Code Online (Sandbox Code Playgroud)

如你看到的:

count += await returnNumberAsync(number)
Run Code Online (Sandbox Code Playgroud)

在4个闭包中的每个闭包中,countawaits解析之前被视为0 ,因此仅在最终的await微任务中解析为

count += await returnNumberAsync(4)
// or
count = 0 + await returnNumberAsync(4)
// or
count = 4
Run Code Online (Sandbox Code Playgroud)

确实4分配给count。其他数字已分配给count较早的事实将被忽略。它们确实发生了,但是最终迭代的分配是您在当前代码中看到的全部。

  • 那确实是一个隐藏的陷阱(是的,使用单线程语言并发)...`count = await fn()+ count;也可以工作 (2认同)