2014-11-04 49 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