同步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 :( });