Promise.all() 中的第一个承诺无法正确执行

H.B*_*.B. 2 javascript asynchronous promise async-await

wait函数用作睡眠函数,fn函数接受一个数组(项目),它记录每个项目并在记录下一个项目之前休眠一秒钟。

const wait = async(time) => {
  return new Promise((resolve) => setTimeout(resolve, time))
}

const fn = async(items) => {
  for (item of items) {
    await wait(1000)
    console.log(item)
  }
}

const exeAll = async() => {
  Promise.all([
    fn(['A1', 'A2']),
    fn(['B1', 'B2']),
  ])
}

exeAll()
Run Code Online (Sandbox Code Playgroud)

问题是exeAll函数提供的结果打印:

B1
A2
B2
B2
Run Code Online (Sandbox Code Playgroud)

但我认为它应该打印类似的内容:

A1
B1
A2
B2
Run Code Online (Sandbox Code Playgroud)

执行上述代码时,A1根本不显示。有人能解释一下为什么吗?

Fel*_*ing 10

for (item of items) {将创建一个隐式全局变量item,即多次调用fn将相互干扰,覆盖item。正确声明变量,它会按预期工作:

const wait = async(time) => {
  return new Promise((resolve) => setTimeout(resolve, time))
}

const fn = async(items) => {
  for (let item of items) {
  //   ^^^^
    await wait(1000)
    console.log(item)
  }
}

const exeAll = async() => {
  Promise.all([
    fn(['A1', 'A2']),
    fn(['B1', 'B2']),
  ])
}

exeAll()
Run Code Online (Sandbox Code Playgroud)


我们可以添加更多日志记录以fn查看在您的情况下会发生什么:

const wait = async(time) => {
  return new Promise((resolve) => setTimeout(resolve, time))
}

let counter = 0;
const fn = async(items) => {
  const c = counter++;
  console.log(`enter fn call #${c}`);
  for (item of items) {
    console.log(`fn call #${c} sets item <-`, item);
    await wait(1000)
     console.log(`fn call #${c} reads item ->`, item);
    console.log(item)
  }
}

const exeAll = async() => {
  Promise.all([
    fn(['A1', 'A2']),
    fn(['B1', 'B2']),
  ])
}

exeAll()
Run Code Online (Sandbox Code Playgroud)


严格模式 ( "use strict";) 会捕获该错误,因为分配给未声明的变量会引发错误。

  • 严格模式(`“use strict”;`)会捕获这一点,因为分配给未声明的变量会引发错误;) (4认同)