组员大眼瞪小眼,forEach处理异步任务遇到的坑
背景
大家好,我是zz,时间发生在上周,一位组员遇到一个问题,几个同事都没能帮忙解决,我在这边就开门见山直接描述当时他遇到的问题。他在forEach处理了异步,但是始终不能顺序执行,至此想要的数据怎么都拿不到,组员绞尽脑汁,不知道问题发生在哪里。此篇文章我们就来探究下forEach循环下处理异步会发生什么样的情况。
探索
我们先看一段简单的forEach处理异步的代码
//forEach 处理
let promiseTasek = (num) => {
return new Promise((resolve, rejece) => {
setTimeout(() => {
console.log(num)
resolve(true)
}, 4000)
})
}
function toTaskByForEach() {
const arr = [1, 2, 3, 4, 5, 6]
arr.forEach(async (item) => {
await promiseTasek(item)
})
}
toTaskByForEach()
复制代码
执行结果 注意执行输出的变化,他会直接打印出1,2,3,4,5,6 本来想录制一个gif的,确实没找到一个好的工具录制浏览器的控制台
我们尝试换一种循环for of 看一下效果对比一下
let promiseTasek = (num) => {
return new Promise((resolve, rejece) => {
setTimeout(() => {
console.log(num)
resolve(true)
}, 4000)
})
}
async function toTaskByForOf(){
const arr = [1,2,3,4,5,6]
for (let i of arr) {
await promiseTasek(i)
}
}
toTaskByForOf()
复制代码
来看下执行结果 他会按顺序执行依次打印出1,2,3,4,5,6
所以这是为啥呢
后来我们研究了一下map
//forEach 处理
let promiseTasek = (num) => {
return new Promise((resolve, rejece) => {
setTimeout(() => {
console.log(num)
resolve(true)
}, 4000)
})
}
function toTaskByMap() {
const arr = [1, 2, 3, 4, 5, 6]
arr.map(async (item) => {
await promiseTasek(item)
})
}
toTaskByMap()
复制代码
输出结果和forEach 一样 后来我们发现Array.prototype.forEach 不是一个 async 函数,即使 Array.prototype.forEach 的参数 callback 是 async 函数,也暂停不了 Array.prototype.forEach 函数,map 也是同理
最后
Array.forEach 会并发启动所有方法但是丢弃结果,如果 forEach 需要 await 结果的时候可以用这个方法 await Promise.all(arr.map(async (item) => { /** ... */ }))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!