map/forEach循环里async、await为什么会失效

300 阅读1分钟

为什么map/forEach循环里async、await没有生效

原因:map/forEach内部使用了while结合callback方式来执行函数,await不会等待callback的执行

示例:

const arr = [1, 2, 3, 4];
const request = (num) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(num);
      console.log(`执行${num}`);
    }, 1000);
  });
};

// forEach循环请求(这种方式有问题)
arr.forEach(async (v) => {
  console.log('调用请求之前', v);
  const res = await request(v);
  console.log('调用请求之后', v);
});
console.log('调用请求结束')

执行结果:

调用请求之前 1
调用请求之前 2
调用请求之前 3
调用请求之前 4
调用请求结束
执行1
调用请求之后 1
执行2
调用请求之后 2
执行3
调用请求之后 3
执行4
调用请求之后 4

期待结果

调用请求之前 1
执行1
调用请求之后 1
调用请求之前 2
执行2
调用请求之后 2
调用请求之前 3
执行3
调用请求之后 3
调用请求之前 4
执行4
调用请求之后 4
调用请求结束

解决方案

1、for循环
const handleRequest = async () => {
  for (const v of arr) {
    console.log('调用请求之前', v);
    const res = await request(v);
    console.log('调用请求之后', v);
  }
  console.log('调用请求结束')
};
handleRequest();
2、promise
const handleRequest = async () => {
  const resArr = await Promise.all(
  arr.map(async (v) => {
    const res = await request(v);
      console.log(`调用请求之后,${res}`);
      return res;
    })
  );
  return resArr;
};
handleRequest();