当前位置: 首页 > 知识库问答 >
问题:

javascript - JavaScript forEach 循环:同步任务与执行顺序?

陆安国
2023-12-06

目前生产出现了,handleDealData()返回的结果是[],并非是forEach执行后的数组,此问题偶发。
但是查了资料,解释说forEach的循环是同步任务。

            handleDealData: function () {                var self = this                var initData = self.deepCopyInitData;                console.log("��  initData--->", initData)                var val = []                initData.forEach(function (obj, key) {                    var _newObj_ = {                        impartTarget: self.impartTarget,                        insuredMark: self.insuredMark,                        impartCode: obj.questList.notificationCode,                          showContent: obj.question,                             impartAnser: '',                                          showAnser: obj.active ? self.identity + ':' + obj.remark : '',                        demo: obj.active ? obj.result : ''                    }                    var TAndF = Number(obj.active)                    var allResult = obj.allResult                    if (typeof obj.allResult !== "string") {                        allResult = allResult.join('#')                    }                    _newObj_.showAnser = _newObj_.showAnser.replace(_newObj_.showContent, '')                    _newObj_.impartAnser = TAndF + ',' + allResult                    val.push(_newObj_)                })                return val            },

chrome测试正常,返回非[]
forEach的执行顺序是否跟机型、浏览器有关?

共有3个答案

虞唯
2023-12-06

一、关于 forEach 及其变化

forEach 是同步的,这里的代码抽象一下,可以看到是这个结构:

const newArray = [];  // 产生一个空数组oldArray.forEach(() => {    const aObj = ..;    newArray.push(aObj); // 每次循环插入一个数据});// 得到有数据的 newArray

这个结构可以直接使用 .map 来实现,即把 .forEach() 变更为 .map

const newArray = oldArray.map(() => {   const aOjb = ...;   return aObj});

如果处理过程中存在 if 分支,并不是每次都会 push,那可以在 map 前(或后)使用 filter,来过滤数据。

参阅: JavaScript 数据处理 - 列表篇

二、关于 console.log

console.log 输出的是一个对象,而这个对象在实际渲染输出的时候,使用的是终值,并不一定是 console.log 执行时的值。

如果需要打印如当时的信息,最好是通过 JSON.stringify 或者是选择一部分属性(值)拼接成字符串(用模板字符串比较方便)来显示。注意使用 JSON.stringify 处理对象的时候可能需要处理循环引用问题。

比如

console.log("initData --->", JSON.stringify(initData, null, 2));
方嘉言
2023-12-06

forEach是同步任务,所以就不要老盯着他看了,可以看看其他的地方。

handleDealData返回的val是空数组,val是根据initData循环来的,所以可以看下initData是不是空。

另外,console打印的是快照,也就是你点击展开显示的值和你打印时的值可能不一样(中间你修改了这个数据),所以,可以猜测也有可能是后面更改了val

堵雅健
2023-12-06

JavaScript 的 forEach 循环是按照数组的顺序同步执行每个元素的。这意味着它不会并行执行,而是会等待每个循环都完成后再进行下一个循环。因此,你看到的返回结果是空数组 [] 的问题应该不是由于 forEach 的异步行为导致的。

在你的代码中,forEach 循环遍历 initData 数组的每个元素,并依次执行一系列操作。这些操作包括创建新的对象 _newObj_,对其进行一些处理,然后将新对象添加到 val 数组中。

由于 forEach 是同步执行的,所以你应该期望在循环结束时获得一个包含所有新对象的数组。这个结果应该与你在 Chrome 中看到的正常结果一致。

然而,你提到在生产环境中得到的是空数组。这可能是由于一些其他因素导致的,例如:

  1. 在生产环境中,initData 可能是空的或者未定义。在这种情况下,forEach 会直接返回,不会执行任何循环,因此 val 仍然是空的。
  2. 在生产环境中,可能有其他的代码或操作改变了 val 数组。这可能包括其他部分的代码、异步操作、或者浏览器/设备的特定行为。
  3. 你可能在不同的环境(例如开发环境和生产环境)中运行了不同的版本的 JavaScript 引擎。这可能导致一些微妙的差异,尽管 forEach 的基本行为应该是相同的。
  4. 在某些情况下,JavaScript 的行为可能会受到浏览器或设备的影响。例如,如果浏览器或设备的 JavaScript 引擎对某些特定的代码或操作进行了优化,可能会导致不同的结果。

为了解决这个问题,我建议你检查一下生产环境中的 initData 是否正常,以及是否有其他代码可能改变了 val 数组。你也可以尝试在不同的环境或不同的设备上测试你的代码,看看问题是否仍然存在。如果问题仍然存在,你可能需要进一步调试你的代码,看看是否有其他因素影响了结果。

 类似资料:
  • 问题内容: 我正在像这样的双循环内进行一些计算: 有没有办法让Loop在执行功能之前先完成?或程序在继续执行… 之前知道循环是否完成的任何方式 我可能会错过一些论坛,但是我发现的那些论坛并没有帮助我实现我想要实现的目标,而且我在NodeJS中做到了这一点,同时我也在问是否有现有的图书馆可以实现这一目标。 我忘了加起来,还是应该再问一个问题? 有没有一种方法可以同步进行迭代,即仅在当前迭代完成后才继

  • 主要内容:系统的crontab设置前面学习了 at 命令,此命令在指定的时间仅能执行一次任务,但在实际工作中,系统的定时任务一般是需要重复执行的。而 at 命令显然无法满足需求,这是就需要使用   crontab 命令来执行循环定时任务。 在介绍 crontab 命令之前,我们首先要介绍一下 crond,因为 crontab 命令需要 crond 服务支持。crond 是 Linux 下用来周期地执行某种任务或等待处理某些事件的一

  • 这是在一次Android采访中被问到的。有人问我是否可以从异步任务 1 的 doInBackground() 方法(让它成为 Task1)启动另一个异步任务(让它成为 Task2)。我浏览了文档,其中说了以下内容: 必须在UI线程上创建任务实例。 必须在 UI 线程上调用 execute(Params...)。 根据这些陈述,我认为从另一个任务的后台方法启动一个任务是不可能的。此外,async任务

  • 在Server程序中如果需要执行很耗时的操作,比如一个聊天服务器发送广播,Web服务器中发送邮件。如果直接去执行这些函数就会阻塞当前进程,导致服务器响应变慢。 Swoole提供了异步任务处理的功能,可以投递一个异步任务到TaskWorker进程池中执行,不影响当前请求的处理速度。 程序代码 基于第一个TCP服务器,只需要增加onTask和onFinish 2个事件回调函数即可。另外需要设置task

  • 问题内容: 我正在使用python更新一些LED。我一直在这样做: 我想用Flask充当一些我可以在我的浏览器中运行的ReactJS前端(以更改当前模式等)与Python中的LED控制代码之间的桥梁。 我的Flask工作正常,可以处理HTTP请求,等等。我想知道如何设置我的flask应用程序同时连续运行(或快速运行),同时仍然能够相互通信,就像这样: 我遇到了,这似乎可以解决问题,但对于我的问题有

  • 问题内容: 我已经搜索了很多,但是找不到任何解决方案。我以这种方式使用Java线程池: 以这种方式,任务以随后的顺序执行(如在队列中)。但是我需要更改“选择下一个任务”策略。所以我想为每个任务分配优先级(不是线程优先级),并执行与这些优先级相对应的任务。因此,当执行者完成另一个任务时,它将选择下一个任务作为具有最高优先级的任务。它描述了常见问题。也许有一种更简单的方法没有说明优先级。它选择上一个添