【问题标题】:Updating values from a asynchronous foreach safely?安全地从异步 foreach 更新值?
【发布时间】:2011-12-19 13:08:02
【问题描述】:

我有一个异步 forEach 循环遍历数组 var anArray = [.....values inside...];

        anArray.forEach(function (s) {
           ...
        });

还有两个将要更新的全局变量:

var count = 0;
var total = 0;

在 foreach 期间,我将更新这两个变量。由于 foreach 是异步的,我可能希望多个迭代同时运行。这意味着我的变量可能会被覆盖。

对于count,这很好,因为我所做的只是在每个循环中计数++。

但是对于total,每次查看都会添加不同的值。

我有什么办法可以确保total 会在不损失任何精度的情况下更新??

【问题讨论】:

  • “精度”是什么意思?您是否依赖于total 的构建顺序,这可能会导致精度问题,即a + b + cc + b + a
  • 什么是“异步 forEach”?
  • @nnnnnn 道歉。我曾假设 Array.forEach 是异步的,但是在阅读了这里的一些答案之后。好像没有!
  • @pimvdb 嗯,让我在这里尝试解释一下,我担心是否存在c=a+b同时出现f=a+c的情况。然后可能不会捕获添加bc
  • 无需道歉。不确定您是否被forEach() 将回调函数作为参数这一事实愚弄了,但是有很多同步函数可以做到这一点。如果您没有使用setTimeout()setInterval() 或ajax 函数,那么您很可能没有处理异步代码。如果您使用 setTimout() 编写自己的异步“循环”,那么理论上您可能会遇到多个代码块更新相同变量的问题(即使非 web-worker JS 仅在一个线程上执行)。

标签: javascript asynchronous foreach


【解决方案1】:

Javascript 中没有线程。 “异步”仅仅意味着它将事件发布到队列中,然后在主线程可用时对其进行评估。因此,您永远不会在 JS 中遇到任何类型的同步问题。

例如,如果你运行:

setTimeout(function() {doSomeStuff1For(10secs)},1)
setTimeout(function() {doSomeStuff2For(20secs)},1)

这些事件将像这样执行(考虑到 10 秒的调用很幸运能成为第一个):

1 sec: doSomeStuff1
2 sec: doSomeStuff1
...
10 sec: ended doSomeStuff1
11 sec: started doSomeStuff2
...
30 sec: ended doSomeStuff2.

【讨论】:

    【解决方案2】:

    我认为count++total += 10 工作方式相同,因此不会有任何区别。但无论如何都没关系:。 Javascript 不会并行执行代码

    另请参阅:http://ejohn.org/blog/web-workers/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多