通过一个 BUG 提醒大家,不要过度依赖 Foreach !

文章通过一个编程bug指出不应过度依赖forEach处理异步操作,因为在forEach中使用async/await不会产生排队效果,导致数据获取失败。推荐使用Promise.all解决异步排队问题,并提倡根据需求合理使用filter、map和reduce等方法。同时强调forEach的缺点,如无法中断和进行异步控制,而for循环可以提供这些功能。
摘要由CSDN通过智能技术生成

通过一个 BUG 提醒大家,不要过度依赖 Foreach !

最近写代码时遇到一个bug,问题就是列表渲染不出来,拿不到数据,代码如下

const data = []
const urls = ['name1', 'name2']
urls.forEach(async (url) => {
  const v = await request(url)
  data.push(v)
})
this.data = data
// 一直是空数组
console.log(this.data)

这个问题还是先了解forEach的实现原理是什么

forEach 实现原理

forEach的实现原理非常简单,如下:

Array.prototype.myForEach = function(callback) {
  for (let i = 0; i < this.length; i++) {
    callback(this[i], i, this);
  }
}

所以说,在 forEach中使用 async/await 是不可取的,因为它的 callback 是并行执行的,并没有排队效果,那么 data 自然就获取不到,因为 async 是异步的

解决问题

所以需要使用 Promise.all 即可

const urls = ['api1', 'api2']
const data = await Promise.all
  urls.map(url => request(url))
)
this.data = data

不要过度依赖 forEach

很多人都基本只用 forEach,但是它是有很多缺点的

  • 无法中断
  • 无法进行异步排队

所以不要过度依赖它

中断、排队 可以用 for

其实直接用 for 循环也可以实现排队、中断的效果,这都是 forEach做不到的

data.forEach(item => {
  // 没有效果
  if (xxx) break;
})

for (let item of data) {
  // 有效果
  if (xxx) break;
}
data.forEach(async item => {
  // 没有效果
  await item()
})

for (let item of data) {
  // 有效果
  await item()
}

合理使用 filter、map、reduce

如果你需要过滤一个数组,可以使用 filter

const result = []
data.forEach(item => {
  if (item.flag) {
    result.push(item)
  }
})

// 用 filter
const result = 
data.filter(({ flag }) => flag)

如果你需要格式化数组数据,你可以使用 map

const result = []
data.forEach(item => {
  result.push({
    name: item.name,
    age: `${item.age}`
  })
})

// 使用 map
const result = 
data.map(item =({
  name: item.name,
  age: `${item.age}`
}))

如果你需要累计,你可以使用 reduce

const sum = 0
nums.forEach(num => {
  sum += num
})

// 使用 reduce
const sum = 
nums.reduce((pre, next) => {
  const v = pre + next
  return v
}, 0)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vue1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值