同步forEach循环(等待它结束)

我在Node.js中有一个函数,它接受一个数组并循环,对每个元素进行一些耗时的计算。

这是一个超简化版本的function:

var analyze_data = function (data) { data.forEach(function (elm) { if (elm.myProp == true) { return true; } }); return false; } 

从本质上讲,如果任何元素的属性myProp等于true,我希望函数返回true。 如果没有元素满足这个条件,函数应该返回false。

但是,代码永远不会等待forEach循环完成。 换句话说,如果数组中的第100个元素满足条件,则函数应该返回true。 相反,它跳过return false; 并在forEach循环有时间完成之前返回false。

有针对这个的解决方法吗?

编辑

所以我意识到我简化了我的问题 – 我实际上使用了Node.js包es6-promise ,而我的代码看起来更像这样:

 var analyze_data = function (data) { return new Promise(function (resolve, reject) { data.forEach(function (elm) { if (elm.myProp == true) { resolve(elm); } }); resolve(false); }); } 

所以在现实中,我没有在forEach函数而不是外部函数中返回值的问题。 此外,请注意函数如何parsing为元素本身,而不是true,否则为false。 如果其中一个元素通过了条件,我实际上想要返回一些相关的数据,否则返回false表示它们全部失败。

现在有什么想法? :p另外,谢谢所有的原始答案!

这不是同步/asynchronous执行的问题。 你正在做的是在每个callback(对于你的analyze_data函数是不可见的)中返回true,然后在forEach完成后返回false。

你需要使用Array.prototype.some

 var analyze_data = function (data) { return data.some(function (elm) { return elm.myProp == true; }); } 

你的问题不是这样的事实,forEach是asynchronous的,因为它不是。 但是,因为你错误的回报另一个。

你不是从你的主函数返回true的callback。

forEach调用forEach,因为它执行数组上的每个元素,所以不能停在中间。 以下是文档摘录:

注意:没有办法停止或破坏forEach循环。 解决方法是使用Array.every或Array.some。

问题在于你从内部函数返回true的值,而不是在外部函数中捕获它。 如果你这样做,它应该工作:

 var retVal = false; data.forEach(function (elm) { if (elm.myProp == true) { retVal = true; } }); return retVal; 

现在你有两个function:

 var analyze_data = ***function (data)*** { data.forEach(***function (elm)*** { if (elm.myProp == true) { return true; //returns out of function(elm) } }); //the true value is gone - you didn't do anything with it return false; //always returns false out of function(data) } 

编辑:

 data.forEach(function (elm) { if (elm.myProp == true) { resolve(elm); } }); resolve(false); 

你现在(可能)决定elm ,但总是在这之后解决为false 。 我不是100%肯定的行为,但我猜测后面的一个会覆盖第一个。 所以再次,你需要检查:

 is_found = false; data.forEach(function (elm) { if (elm.myProp == true) { resolve(elm); is_found = true; } }); if (!is_found) { resolve(false); } 

当然,这似乎应该是你应该做的:

 if (!is_found) { reject(false); } 

那么你可以这样做:

 promise.then(function(result) { // do stuff since it found stuff :) }, function(err) { // do stuff since if didn't find anything :( });