2014-11-04 40 views
2

我有一个包含各种数据的大数组,以及一个对数组执行一些基本的但有点耗时的分析的函数。我使用forEach循环遍历数组。我想如果条件满足时,函数返回一个特定的元素,否则为false,使用的承诺,因为函数可能需要相当长的时间来完成:以下代码是否等待forEach完成

var analyzeData = function (arr) { 
    return new Promise(function (resolve, reject) { 
     var answer = false; 

     arr.forEach(function (elm) { 
      if (elm.foo == true) { 
       answer = elm; 
      } 
     }); 

     resolve(answer); 
    }); 
} 

我现在遇到的问题是,我怀疑在forEach循环完成之前正在解析answer;即在forEach循环可以完成检查每个元素的foo属性之前,该功能解析为answer,其默认为false。

有没有办法确保forEach循环后面的代码等待循环完成迭代,或者以某种其他方式遍历数组?

+2

'Array.prototype.forEach()'是同步的。所以它完成了对所有数组元素的迭代,只有解释器才会计算下一个语句。 – zerkms 2014-11-04 20:53:38

+0

@zerkms我也这么认为 - 任何想法为什么我会遇到这个问题呢? – apparatix 2014-11-04 20:55:32

+3

@apparatix:我们不知道你遇到什么问题。你应该[创建一个最小,完整和可验证的例子](http://stackoverflow.com/help/mcve)。 – ruakh 2014-11-04 20:56:16

回答

2

JavaScript循环迭代是同步的,并且在您的代码中,您将始终在调用resolve之前完成循环。

请注意,JavaScript也是单线程的,所以把它放在承诺中不会让它在后台运行。在此循环执行期间,UI仍不会响应用户的某段时间。

您可以使用web workers将一些计算卸载到后台进程。

另一方面:当找到第一个项目时,可以退出循环吗?如果没有,为什么不反向迭代(使用for循环,而不是数组反转),并在找到第一个项目时退出?在最坏的情况下,它在技术上仍然是O(N),但最好的情况是O(1),如果你尽快纾困。

但是为了更有帮助,您需要提供更多关于正在发生的事情的信息。我会建议在http://jsfiddle.net/上加一个小例子 - 这本身可以是一个有用的练习。

+0

感谢您的详细解答德鲁!这个问题实际上存在于我以前做的API调用中:/另外,我使用Promises而不是用于异步/后台计算,但是因为返回值可能不会立即可用 - 如果我只是使用'return',函数有时评估为undefined – apparatix 2014-11-05 00:34:52

+0

@apparatix,很高兴它有帮助。在你展示的情况下,除非你不想在稍后才开始计算,否则不需要承诺。 – 2014-11-05 00:38:46