map、for、forEach调用异步函数的区别

前言

  • map 会先把同步操作执行完,并返回。之后再一次次的执行异步任务
  • for 是等待异步返回结果后再进入下一次循环
  • forEach 无法实现 async、await 同步效果,实际是异步执行

map 函数原理

  1. 循环数组,把数组每一项的值,传给回调函数
  2. 将回调函数处理后的结果 push 到一个新的数组
  3. 返回新数组

map 函数是同步执行的,循环每一项时,到给新数组值都是同步操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const arr = [1, 2, 3, 4, 5];
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("data");
}, 1000);
});
}

const result = arr.map(async () => {
console.log("start");
const data = await getData();
console.log(data);
return data;
});
console.log(result);

// 5次 start -> 遍历每一项开始
// (5)[Promise, Promise, Promise, Promise, Promise] -> 返回的结果
// 1秒后输出5次 data -> 遍历每一项异步执行返回的结果

代码执行结果:

  • map 不会等到回调函数的异步函数返回结果,就会进入下一次循环
  • 执行完同步操作后,就会返回结果,所以 map 返回的值是 promise

使用 for

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const arr = [1, 2, 3, 4, 5];
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("data");
}, 1000);
});
}

(async () => {
for (let i = 0, len = arr.length; i < len; i++) {
console.log(i);
const data = await getData();
console.log(data);
}
})();
// 0
// 1s后输出 data、1
// 1s后输出 data、2
// 1s后输出 data、3
// 1s后输出 data、4
// 1s后输出 data

forEach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const arr = [1, 2, 3, 4, 5];
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("data");
}, 1000);
});
}

arr.forEach(async (item, index) => {
console.log(index);
const data = await getData();
console.log(data);
});
// 立即输出 0、1、2、3、4
// 1s后输出 5个data