JavaScript 循环:如何处理 async/await

同步循环

很久以前我写的循环是这样的:

for (var i=0; i < array.length; i++) {
  var item = array[i];
  // do something with item
}

后来 JavaScript 提供了很多新的特性,现在我们会更倾向于用下面这种写法:

array.forEach((item) => {
  // do something with item
});

在开发过程可能会有这么一种需求,我们需要在循环中异步处理 item,那么可以怎么做呢?

异步循环

如何在循环中使用 await?我们试着写一个异步函数,然后 await 每一次循环任务。

async function processArray(array) {
  array.forEach(item => {
    // define synchronous anonymous function
    // IT WILL THROW ERROR!
    await func(item);
  })
}

这个代码会抛出一个错误,因为我们不能在同步方法中使用 await, processArray 确实是异步函数,但是 array.forEach 里的匿名函数是同步的。

1. 不要等待结果

要处理这个问题,我们可以把这个匿名函数定义为异步的:

async function processArray(array) {
  array.forEach(async (item) => {
    await func(item);
  })
  console.log('Done!');
}

但是这样的话 forEach 方法就相当于异步的了,不会等待遍历完所有的 item,例如下面这段代码:

function delay() {
  return new Promise(resolve => setTimeout(resolve, 300));
}

async function delayedLog(item) {
  // notice that we can await a function
  // that returns a promise
  await delay();
  console.log(item);
}
async function processArray(array) {
  array.forEach(async (item) => {
    await delayedLog(item);
  })
  console.log('Done!');
}

processArray([1, 2, 3]);

将会输出:

Done!
1
2
3

如果你不需要等待这个循环完成,这样就已经可以了。但是大部分情况我们还是需要等待这个循环完成才进行之后的操作。

2. 串行遍历

要等待所有的结果返回,我们还是要回到老式的 for 循环写法:

async function processArray(array) {
  for (const item of array) {
    await delayedLog(item);
  }
  console.log('Done!');
}

最后的结果符合我们的预期:

1
2
3
Done!

上面这段的遍历代码是串行执行的,我们也可以把它换成并行的。

3. 并行遍历

我们可以稍微更改上面的代码来编程并行的:

async function processArray(array) {
  // map array to promises
  const promises = array.map(delayedLog);
  // wait until all promises are resolved
  await Promise.all(promises);
  console.log('Done!');
}

(注意:对于特别大的数组不建议使用这种写法,太多的并行任务会加重 CPU 和内存的负荷)

原文:https://lavrton.com/javascript-loops-how-to-handle-async-await-6252dd3c795/
转载:https://zhuanlan.zhihu.com/p/31000936

### 回答1: JavaScriptasync/await 是用来处理异步操作的一种语法糖。它允许我们在异步函数使用同步的法。 我们可以使用 async 关键字来声明一个 async 函数,在 async 函数,我们可以使用 await 关键字来等待一个异步操作的结果。 例如,我们可以使用 async/await 来等待一个 HTTP 请求的响应: ``` async function getData() { const response = await fetch('https://example.com/data.json'); const data = await response.json(); return data; } ``` 使用 async/await 可以让我们使用同步的法来处理异步操作,这样就可以避免使用回调函数和 Promise.then() 方法了。 注意:async/await 只能在函数使用,不能在全局作用域使用。 ### 回答2: JavaScript async/await 是一种编异步代码的新方式。之前,我们通常使用回调函数或者在 Promise 上链式调用 then 方法来处理异步操作。但是这种方式会导致代码嵌套过深,不易阅读和维护。而 async/await 则提供了一种更简洁易读的异步编程语法。 async 函数是一个特殊的函数,它返回一个 Promise 对象。在 async 函数内部,我们可以使用 await 关键字来等待一个 Promise 对象的完成,并且我们可以像同步代码一样直接获取 Promise 的结果。在遇到 await 的时候,代码会暂停执行,等待 Promise 对象的结果返回,然后将结果赋给左侧的变量,继续往下执行。 使用 async/await 可以简化 Promise 的链式调用,并且可以使用 try-catch 捕获异步操作的错误。相对于回调函数或者 Promise 的 .catch 方法,使用 try-catch 更加符合我们的日常编程习惯。 async/await 还可以与其他语法结构一起使用,比如循环和条件语句等,使得我们能够以一种更加直观和顺序的方式来编异步代码。 需要注意的是,await 只能在 async 函数内部使用,而且它只能等待一个 Promise 的完成。如果要同时等待多个 Promise,可以使用 Promise.all 方法。 总之,JavaScript async/await 是一种更加简洁易读的异步编程方式,它可以帮助我们处理异步操作,提高代码的可读性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值