一.不支持处理异步函数
案例:
async function test() {
let arr = [3, 2, 1];
arr.forEach(async (item) => {
const res = await mockSync(item);
console.log(res);
});
console.log("end");
}
function mockSync(x) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(x);
}, 1000 * x);
});
}
test();
// 我们期望的结果是:
// 3;
// 2;
// 1;
// end;
// 但是实际上会输出:
// end;
// 1;
// 2;
// 3;
JavaScript 中的 forEach()方法是一个同步方法,它不支持处理异步函数,如果你在 forEach 中执行了异步函数,forEach()无法等待异步函数完成,它会继续执行下一项,这意味着如果在 forEach()中使用异步函数,无法保证异步任务的执行顺序。
解决:
1.可以使用例如 map()、filter()、reduce()等,它们支持在函数中返回 Promise,并且会等待所有 Promise 完成。
// 使用 map() 和 Promise.all()
const arr = [1, 2, 3, 4, 5];
async function asyncFunction(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num * 2);
}, 1000);
});
}
const promises = arr.map(async (num) => {
const result = await asyncFunction(num);
return result;
});
Promise.all(promises).then((results) => {
console.log(results); // [2, 4, 6, 8, 10]
});
由于我们在异步函数中使用了 await 关键字,map()方法会等待异步函数完成并返回结果,因此我们可以正确地处理异步函数
2.使用 for 循环来处理异步函数
const arr2 = [1, 2, 3, 4, 5];
async function asyncFunction2(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num * 2);
}, 1000);
});
}
async function processArray() {
const results = [];
for (let i = 0; i < arr2.length; i++) {
const result = await asyncFunction2(arr[i]);
results.push(result);
}
console.log(results); // [2, 4, 6, 8, 10]
}
processArray();
二.无法捕获异步函数中的错误
如果异步函数在执行时抛出错误,forEach()无法捕获该错误,这意味着即使在异步函数中出现错误,forEach()仍会继续执行
三.除了抛出异常以外,没有办法中止或跳出 forEach() 循环
forEach()方法不支持使用 break 或 continue 语句来跳出循环或跳过某一项,如果需要跳出循环或跳过某一项,应该使用 for 循环或其他支持 break 或 continue 语句的方法