我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何在Nodejs中使用forEach

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何在Nodejs中使用forEach

如何在Nodejs中使用forEach?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

利用数组对象方法push/shift可实现队列先进先出特性,例如:

>a=[][]>a.push(2.3.4)3>a.push(2)3>a[2.3.4.2]>a.shift()2>a>[3.4.2]

数组与forEach

对数组的删除操作有两种常见方式:delete和使用splice方法,需要明确他们的区别。

操作/方法说明
splice删除并返回指定的数组元素,数组本身长度会改变;但不会free元素对象
delete删除(free)元素对象,数组元素不变,值变为undefined

如果要从数组中彻底删除某个元素,使用splice即可:

> a=[1,2,3][ 1, 2, 3 ]> a.splice(1,1)[ 2 ]> a[ 1, 3 ]> a.length2> a.forEach(function(item, index){console.info("index[", index,"]:", item)});index[ 0 ]: 1index[ 1 ]: 3undefined>

那么,当使用delete删除某个元素对象后,此时执行forEach的效果是什么?

forEach对含空元素数组处理机制

测试结果如下

> a=[1,2,3][ 1, 2, 3 ]> delete a[1]true> a[ 1, , 3 ]> a.length3> a.forEach(function(item, index){console.info("index[", index,"]:", item)});index[ 0 ]: 1index[ 2 ]: 3undefined

从测试结果来看,forEach并不会遍历到值为undefined的哪一项。这在实际应用中如何判断forEach是否结束是一大挑战。

解决配合forEach的异步特性应用,可为数组添加prototype来自行管理设置有效数据;

效果如下:

> a=[1,2,3][ 1, 2, 3 ]> a.validnum=33> delete a[2]true> a.validnum=22> a[ 1, 2, , validnum: 2 ]> a.length3> a.validnum2> a.forEach(function(item, index){console.info("index[", index,"]:", item)});index[ 0 ]: 1index[ 1 ]: 2undefined>

补充:Node.js 数组 forEach 同步处理上下文语句

习惯了C语言系的思维方式,刚接触Node.js,它的异步处理让我头大。

写代码遇到这么一个场景,需要循环对一个数组中的元素进行处理,全部处理完成后再执行一个last操作。但是JS的异步特性会使这个last语句先执行,所以花点时间研究研究forEach。

Talk is cheap. Show me the code.

forEach 用法

forEach用于对数组结构进行遍历,看到有人说forEach底层是用for实现的,没深究,起码效果上看是一样的。forEach的回调函数3个参数分别是:值、序号和原数组。序号从0开始。

(() => {  let arr = [2, 3, 1];  arr.forEach(function (value, index, array) {    console.log(value);    console.log(index);    console.log(array);    console.log('-----');  });})();

Output

20[ 2, 3, 1 ]-----31[ 2, 3, 1 ]-----12[ 2, 3, 1 ]-----

从结果上看forEach多次循环之间是同步的,也就是说都是按顺序执行的。但是一想到它是JS就感觉不可能同步的。。可以验证一下。

forEach 异步处理多次循环

这次在forEach加个定时任务,每次循环操作都延时value相关的时间,模拟比较耗时的操作。

(() => {  let arr = [2, 3, 1];  arr.forEach(function (value, index, array) {    setTimeout(function () {      console.log(value);    }, value*100);  });})();

Output

123

从结果可以看出耗时最短的任务先完成,每次循环的任务并不是按循环的先后顺序执行的,也就是说异步处理多次循环。

forEach 上下文也是异步执行

回到开始说到的问题了,且不管多次循环是不是按顺序执行,我需要forEach中的所有任务都完成后执行一条数据来通知我任务全部完成了。

(() => {  let arr = [2, 3, 1];  arr.forEach(function (value, index, array) {    setTimeout(function () {      console.log(value);    }, value*100);  });  console.log('All the work is done');})();

Output

All the work is done123

从结果来看,上下文的语句也不是同步的,forEach循环中的任务没有完成就通知所有任务都完成了,显然不符合预期。

针对这个问题看了好多个博客,都没有找到合适的解决方法,最后只能想到用Promise.all来勉强实现这个功能。

Promise.all 实现 forEach 上下文语句同步处理

把上面的代码改成Promise.all的结构。每个循环中执行结束调用resolve(),我们知道Promise.all的then函数,只有所有的Promise都执行完成才会触发,这样好像能满足我们的需求。

(() => {  let arr = [2, 3, 1];  let proArr = [];  arr.forEach(function (value, index) {    proArr[index] = new Promise(function (resolve) {      setTimeout(function () {        console.log(value);        resolve();      }, value*100);    });  });  Promise.all(proArr).then(()=>{    console.log('All the work is done');  })})();

Output

123All the work is done

从结果来看,满足了我们的需求。

可能还存在的问题

想到JS异步特性,突然发现可能这个方法还存在个问题。

这里每次 forEach 刚进入就对 Promise 数组进行了赋值操作,这个操作时间应该非常短,循环3次都赋值完成后才调用最后的Promise.all语句。

但是如果这个数组非常大,这个循环赋值的操作非常耗时间的话,假如只完成了一半的赋值操作,那么执行最后这个 Promise.all 的时候传入的 Promise 数组可能并不是包含所有 Promise 的数组。

这样的话 Promise.all 等待的就只有一半的操作,Promise.all 等待的时候,这个数组后面被赋值的 Promise 不知道会不会被等待。

刚接触JS不明白实现机制,只能实验来验证一下是否存在这个问题。接下来用把这个数组弄大一些,请原谅我用最傻瓜式的方式搞大它。

(() => {  let arr = [2, 3, 1, 2, 3, 1, 2, 3, 1, 2];  // 10  arr= arr.concat(arr);  // 2^1 * 10  arr= arr.concat(arr);  // 2^2 * 10  arr= arr.concat(arr);  // 2^3  arr= arr.concat(arr);  // 2^4  arr= arr.concat(arr);  // 2^5  arr= arr.concat(arr);  arr= arr.concat(arr);  arr= arr.concat(arr);  arr= arr.concat(arr);  arr= arr.concat(arr);  // 2^10  arr= arr.concat(arr);  arr= arr.concat(arr);  arr= arr.concat(arr);  arr= arr.concat(arr);  arr= arr.concat(arr);  // 2^15  arr= arr.concat(arr);  arr= arr.concat(arr); // 2^17 * 10// arr= arr.concat(arr);  // 2^18 * 10  console.log(arr.length);  let proArr = [];  arr.forEach(function (value, index) {    proArr[index] = new Promise(function (resolve) {      setTimeout(function () {        console.log(value);        resolve();      }, value*100);    });  });  Promise.all(proArr).then(()=>{    console.log('All the work is done');    console.log(arr.length);  }).catch(function (err) {    console.log(err);  })})();

经过测试在我这个电脑上当数组长度为2^18 * 10的时候,Promise报错 RangeError: Too many elements passed to Promise.all。

当数组长度为2^17 * 10 即2621440的时候,会正常运行。测试了几次,最后的执行命令输出的All the work is done始终在最后输出(因为终端缓冲区太小,所以使用node xx.js > log.txt重定向的方式把输出结果重定向到文件查看)。

当然应用中也不会有这么大的数组,从结果看的话,就是实际应用中不存在上面考虑可能出现的问题。

也就是说可以用 Promise.all 实现 forEach 上下文语句同步处理。

看完上述内容,你们掌握如何在Nodejs中使用forEach的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何在Nodejs中使用forEach

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何在Nodejs中使用forEach

如何在Nodejs中使用forEach?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。利用数组对象方法push/shift可实现队列先进先出特性,例如:>a=[][]>a.pus
2023-06-06

如何在PHP中使用foreach

今天就跟大家聊聊有关如何在PHP中使用foreach,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。语言基础foreach 语法结构提供了遍历数组的简单方式。php5之前, forea
2023-06-15

如何在C#中使用foreach语句

今天就跟大家聊聊有关如何在C#中使用foreach语句,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。C# foreach语句不仅仅只是do...while或者for循环语句的一个变体
2023-06-17

C#中foreach如何使用

本篇文章给大家分享的是有关C#中foreach如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。C# foreach使用1. MySplit 类///
2023-06-17

如何在Vue中使用foreach遍历数组

今天就跟大家聊聊有关如何在Vue中使用foreach遍历数组,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在js中遍历数组//定义班次详细数组 var bcglxiangxiLis
2023-06-15

Linq中如何使用foreach语句

这篇文章给大家介绍Linq中如何使用foreach语句,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Linq 有很多值得学习的地方,这里我们主要介绍Linq foreach语句,包括介绍foreach循环来强制执行查询
2023-06-17

C#中如何使用foreach语句

C#中如何使用foreach语句,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。C# foreach语句示例说明:要对集合中的内容进行增删改的操作,那么就是要遍历集合,那么C
2023-06-17

如何在php中使用foreach遍历二维数组

今天就跟大家聊聊有关如何在php中使用foreach遍历二维数组,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。PHP开发环境搭建工具有哪些一、phpStudy,是一个新手入门最常用的
2023-06-14

nodejs中如何使用JWT

这篇“nodejs中如何使用JWT”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“nodejs中如何使用JWT”文章吧。什么是
2023-07-04

PHP的foreach()如何使用

PHP的foreach()如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。PHP的foreach()总共有两种用法,今天我们就将这两种用法分别作了介绍,并
2023-06-17

Vue中如何使用foreach遍历数组

本篇内容介绍了“Vue中如何使用foreach遍历数组”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在js中遍历数组//定义班次详细数组
2023-07-04

await在forEach中不起作用如何解决

这期内容当中小编将会给大家带来有关await在forEach中不起作用如何解决,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。首先引一个很简单题目:给一个数组,每隔1s打印出来.这里我把我一开始在项目中的代
2023-06-06

foreach与collection怎么在mybatis 中使用

foreach与collection怎么在mybatis 中使用?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。foreach的主要用在构建in条件中,它可以在SQL语句中进
2023-05-31

nodejs 如何使用

Node.js 是一个运行在服务器端的 JavaScript 运行时环境,它能够解析和执行 JavaScript 代码。Node.js 很容易上手,因为 JavaScript 是世界上最流行的编程语言之一,并且 Node.js 有着庞大的社区支持和不断更新的文档资源。本文将介绍如何安装和使用 Node.js。## 安装 Node.jsNode.js 的安装很简单。首先需要前往
2023-05-16

如何在 PHP 中找到 foreach 索引

在本文中,我们将介绍查找 foreach 索引的方法。使用 key 变量使用 index 变量同时使用 key 和 index 变量在 PHP 中使用 key 变量查找 foreach 索引变量键将每个值的索引存储在 foreach 循环中
如何在 PHP 中找到 foreach 索引
2024-02-27

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录