重学 JS:为啥 await 不能用在 forEach 中详解

当我们使用 async/await 来处理异步函数时,有可能会遇到在 forEach 循环中使用 await 语句,导致 await 处理不完整的问题,这是因为 forEach 循环的特殊性导致的。

问题

forEach 循环是 JavaScript 提供的一种遍历数组的方式,常用于对数组中的每一项进行操作,语法如下:

array.forEach(callback(currentValue [, index [, array]]) {
  // 处理逻辑
}[, thisArg]);

其中 callback 是一个函数,用于处理数组中的每一项,currentValue 是数组中的当前项,index 是当前项的索引位置,array 是数组本身,thisArg 是执行 callback 时的 this 值,默认是 undefined

forEach 中使用 await 的问题就在于,await 只会等待 Promise 对象完成,然而 forEach 并不会等待回调函数完成,而是在每次调用回调函数之后立即执行下一轮循环,导致 await 处理不完整。

以下是一个示例:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const array = [1, 2, 3];
array.forEach(async item => {
  await delay(1000);
  console.log(item);
});

console.log('done');

在这个示例中,我们使用了 delay 函数来延迟 1 秒钟,然后在 forEach 循环中使用 await 来等待这个延迟。但是,我们会发现 done 被先输出了,然后才是数组中的每一项,这是因为 forEach 循环不会等待回调函数的完成。

解决方案

解决这个问题的方法之一是使用 for...of 循环,因为 for...of 会等待每一个循环体内的异步操作完成,而不是像 forEach 那样不等待直接执行下一次循环。

以下是一个 for...of 的示例:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const array = [1, 2, 3];
for (const item of array) {
  await delay(1000);
  console.log(item);
}

console.log('done');

在这个示例中,我们使用了 for...of 循环,将数组中的每一项作为变量 item,然后使用 await 语句等待 delay 函数的延迟完成。这个示例会正确输出数组中的每一项,然后输出 done,说明 for...of 循环可以正确地等待异步操作完成。

另外一种解决方案是使用 Promise.all 来并行执行异步任务,然后使用 map 方法将每个任务映射为一个 Promise 对象,代码如下:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const array = [1, 2, 3];
await Promise.all(array.map(async item => {
  await delay(1000);
  console.log(item);
}));

console.log('done');

在这个示例中,我们使用 Promise.all 来并行执行异步任务,然后使用 map 方法将每个任务映射为一个 Promise 对象,然后使用 await 语句等待所有 Promise 对象的完成。这个示例也会正确输出数组中的每一项,然后输出 done

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:重学 JS:为啥 await 不能用在 forEach 中详解 - Python技术站

(1)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • 在Windows上安装Node.js模块的方法

    下面是在Windows上安装Node.js模块的方法的完整攻略: 步骤一:安装Node.js 下载Node.js 首先需要从官网下载Node.js的安装程序,网址是 https://nodejs.org。 安装Node.js 下载完成后,双击安装程序进行安装,按照提示进行操作。注意选择安装路径以及在安装过程中是否需要添加到系统环境变量。 若已经安装过Node…

    node js 2023年6月8日
    00
  • nodejs中安装ghost出错的原因及解决方法

    安装 Ghost 是搭建博客的必要步骤之一,但在安装过程中可能会遇到错误,这篇攻略将详细讲解在 Node.js 中安装 Ghost 出错的原因及解决方法。 问题描述 在使用命令 npm install -g ghost 安装 Ghost 时,可能会遇到以下错误: gyp ERR! build error gyp ERR! stack Error: `make…

    node js 2023年6月8日
    00
  • 浅析nodejs实现Websocket的数据接收与发送

    浅析Node.js实现WebSocket的数据接收与发送 什么是WebSocket WebSocket是一种在单个TCP连接上进行全双工通信的协议。它使得客户端和服务器端之间可以进行实时数据交换和数据推送而无需采取轮询方式,从而减少了网络流量和延迟。 WebSocket的实现过程 从客户端到服务器 客户端和服务器握手建立连接,此时会发送HTTP header…

    node js 2023年6月8日
    00
  • TypeScript手写一个简单的eslint插件实例

    下面是详细的攻略: 准备工作 安装相关依赖: npm install -D typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin 其中,typescript 是需要判断的语言,parser 是将代码解析成 AST(Abstract Syntax Tree)的工具,eslin…

    node js 2023年6月8日
    00
  • node.js开发辅助工具nodemon安装与配置详解

    Node.js开发辅助工具nodemon安装与配置详解 什么是nodemon? nodemon是一个node.js应用程序的开发工具。它会监视您代码的更改并自动重启应用程序。因此,您无需在每次更改代码后手动重启应用程序,这在开发过程中非常方便。 安装nodemon 要安装nodemon,请打开终端并输入以下命令: npm install -g nodemon…

    node js 2023年6月8日
    00
  • nodejs实现jwt的示例代码

    请允许我详细讲解 “Node.js 实现 JWT 的示例代码” 的完整攻略。 概述 JWT(Json Web Token)是一种安全跨域的验证和交互方式,可以在不同的服务之间传递信息,而无需了解或共享用户登录信息。它由头部、载荷和签名组成,被称为 jwt 的三个部分。使用 Node.js 实现 JWT 是比较简单的,接下来我们就来看如何编写代码。 安装依赖 …

    node js 2023年6月8日
    00
  • JavaScript树形组件实现无限级树形结构

    以下是“JavaScript树形组件实现无限级树形结构”的完整攻略。 什么是树形结构? 树形结构是计算机科学中非常常见的一种数据结构,它类似于现实生活中的树,由一个根节点和多个子节点组成。树形结构具有递归的性质,每个节点都可以看作一个子树。 树形结构在网站中的应用 在网站中,我们会经常遇到需要展示树形结构的场景,比如商品分类、组织架构、地区选择等。为了方便展…

    node js 2023年6月8日
    00
  • Nodejs 复制文件/文件夹的方法

    当我们需要将文件或文件夹从一个位置复制到另一个位置时,Node.js为我们提供了一个内置的模块——fs(文件系统模块)。使用该模块,我们可以方便地进行文件和文件夹的复制。 复制文件 我们可以使用fs.createReadStream()方法创建一个可读流,然后将其复制到另一个可写流中,如下所示: const fs = require(‘fs’); const…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部