index

文章介绍了如何在JavaScript中实现异步循环的同步行为,对比了for循环、map方法和forEach方法。推荐使用map方法结合Promise.all来实现,因为这种方式在异步操作之间保持了并行性,提高了效率。for循环虽然也能实现同步,但每个异步操作会依次执行,效率较低。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

异步循环同步实现

先定义一个异步操作

const fn = (num) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(num * 10);
      resolve(num)
    }, 4000);
  })
}

1.for

/**
 * for 循环实现异步循环同步
 */
const fn2 = async (array) => {
    for (let index = 0; index < array.length; index++) {
      console.log(array[index] * 100);
      await fn(array[index]) //1
      console.log(array[index]);
    }
  }

  !(async () => {
    await fn2([1, 2, 3])
    console.log(1111);
  })()
// 输出值:
// 100
// 10
// 1
// 200
// 20
// 2
// 300
// 30
// 3
// 1111

2.map(推荐)

/**推荐
 * map方法,实现异步循环同步
 */
!(async () => {
  await Promise.all([1, 2, 3].map(async e => {
    console.log(e * 100);
    await fn(e)
    console.log(e);
  }))
  console.log(1111);
})()
// 输出值:
// 100
// 200
// 300
// 10
// 1
// 20
// 2
// 30
// 3
// 1111
// 原理:结合map的返回值为Promise的数组,再使用Promise.all 方法使整个异步操作变为同步,而且异步之间仍是异步
/**

注意

forEach无法实现异步循环同步

总结

  1. forEach无法实现异步循环同步,for、map 可以实现异步循环同步
  2. for、map 中推荐使用map,因为上面的输出中for循环的异步操作是一个个同步执行的,而map异步之间是异步执行的,效率明显高于for

扩展

async await :
简单理解就是Promise的.then的语法糖
理解:async await 后面的代码相当于.then 后面的代码
所以在上面的异步循环中await后面的代码相当于在Promise.then的里面是微任务,如果最外层不加await则会被最后执行

!(async () => {
  // .then
  fn(20).then((data) => {
    console.log(data);
  })

  // await
  const data = await fn(20)
  console.log(data);
  // 上面两个写法最终执行相等
})()

代码总结

const fn = (num) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(num * 10);
      resolve(num)
    }, 4000);
  })
}
/**
 * forEach 无法实现异步循环同步
 */
[1, 2, 3, 4, 5, 6].forEach(async e => {
  console.log(e * 100);
  const _fn = await fn(e) //1
  console.log(e);
});
/**
 * for 循环实现异步循环同步
 */
const fn2 = async (array) => {
    for (let index = 0; index < array.length; index++) {
      console.log(array[index] * 100);
      await fn(array[index]) //1
      console.log(array[index]);
    }
  }!(async () => {
    await fn2([1, 2, 3])
    console.log(1111);
  })()
  // 输出值:
  // 100
  // 10
  // 1
  // 200
  // 20
  // 2
  // 300
  // 30
  // 3
  // 1111

  /**推荐
   * map方法,实现异步循环同步
   */
  !(async () => {
    await Promise.all([1, 2, 3].map(async e => {
      console.log(e * 100);
      await fn(e)
      console.log(e);
    }))
    console.log(1111);
  })()
  // 输出值:
  // 100
  // 200
  // 300
  // 10
  // 1
  // 20
  // 2
  // 30
  // 3
  // 1111
  // 原理:结合map的返回值为Promise的数组,再使用Promise.all 方法使整个异步操作变为同步,而且异步之间仍是异步
  /**
   * 总结:
   * 1.forEach无法实现异步循环同步,for、map 可以实现异步循环同步
   * 2.for、map 中推荐使用map,因为上面的输出中for循环的异步操作是一个个同步执行的,而map异步之间是异步执行的,效率明显高于for
   */
  /**
   * 扩展
   * async await :
   * 简单理解就是Promise的.then的语法糖
   * 理解:async await 后面的代码相当于.then 后面的代码
   * 所以在上面的异步循环中await后面的代码相当于在Promise.then的里面是微任务,如果最外层不加await则会被最后执行
   */
  !(async () => {
    // .then
    fn(20).then((data) => {
      console.log(data);
    })
    // await
    const data = await fn(20)
    console.log(data);
    // 上面两个写法最终执行相等
  })()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值