Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronous forEach loop (wait for it to end)

I have a function in Node.js that takes in an array and loops through it, doing somewhat time-consuming computations on each element.

Here's a super-simplified version of the function:

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

Essentially, I want the function to return true if any of the elements' property myProp is equal to true. If none of the elements satisfy this condition, the function should return false.

However, the code never waits for the forEach loop to finish. In other words, if the 100th element in the array satisfies the condition, the function should return true. Instead, it skips to return false; and returns false before the forEach loop has time to finish.

Is there a solution to this?

Edit

So I realized that I oversimplified my question - I'm actually using the Node.js package es6-promise, and my code looks more like this:

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

So in reality, I don't have the issue of returning a value in the forEach function rather than the outer function. Additionally, notice how the function resolves to the element itself rather than true, otherwise false. I actually want to return some relevant data if the one of the elements passes the condition, otherwise false to indicate that they all failed.

Any ideas now? :p Also, thanks for all the original answers!

like image 999
apparatix Avatar asked Oct 31 '14 15:10

apparatix


2 Answers

It is not a question of sync/async execution. What you are doing is returning true in the for each callback (which is invisible for your analyze_data function), then returning false after forEach is finished.

You need to use Array.prototype.some:

var analyze_data = function (data) {
    return data.some(function (elm) {
        return elm.myProp == true;
    });
}
like image 112
manji Avatar answered Sep 29 '22 00:09

manji


Your problem is not the fact that forEach is async, because it is not. But because you mistake one return for another.

You return true from callback not from your main function.

forEach called forEach because it executes for each element on the array, you can't stop in the middle. Here is the excerpt from documentation:

Note: There is no way to stop or break a forEach loop. The solution is to use Array.every or Array.some.

like image 21
exebook Avatar answered Sep 29 '22 01:09

exebook