组员大眼瞪小眼,forEach处理异步任务遇到的坑

本文探讨了在JavaScript中,forEach和forOf循环处理异步任务的区别,展示了forEach不阻塞执行导致的并行输出,而forOf则按顺序执行。通过map和awaitPromise.all的方法进行深入解析,适合理解异步编程在数组操作中的行为。

背景

大家好,我是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) => { /** ... */ }))

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值