Using break and continue in each () and forEach ()

I'm not sure I understand the meaning of the functional style loop / match if we cannot use the break and continue keywords.

I can do it:

collections.users.models.forEach(function(item, index) {
    //can't use break or continue...?
});

      

or I can do this:

for (var i = 0; i < collections.users.models.length; i++) {
     if (user.username === collections.users.models[i].username) {
         app.currentUser = collections.users.models[i];
         break;
     }
}

      

What's the benefit of a function call if I can't use the break or continue keywords?

+3


source to share


5 answers


Using Array.prototype.some

and Array.prototype.every

to continue / exit functionality for loops is a good thing to do



[1,2,3,null,5].every(function(v){
    if(!v) return false;  // this will break out of the loop
    // do your regular loopage lulz
});

      

0


source


.each()

or .forEach()

less flexible than a simple loop for

. They just are.

As you have found, they offer you less control over your cycle. They are only handy when you want to iterate over the entire set, or when it really helps you automatically create a new function context for your iterative loop code (sometimes useful in asynchronous operations), or when you like more declarative coding in what a method expresses your the intent of the coding is a little more clear and concise than the loop for

. .forEach()

also automatically skips sparse array elements.

Aside from these features, it is just a typing reduction that sacrifices some loop control. Use them when you like one of the benefits, and don't use them when you need more loop control.




FYI, for Javascript arrays, .some()

and .every()

will try to give you some looping control back, although they are still not as flexible as a loop for

.

If you use .some()

, you can return true;

be equivalent break;

(since this will stop the loop) and you can just return;

be equivalent continue;

(since this will return from the callback and move on to the next iteration).

+5


source


To be honest, there are not so many "advantages" as convenience. You can call return

to force yourself to exit one iteration of the loop forEach

, but this is not the same as native for

because you are still calling the function. The convenience comes in the form of not having to parameterize your loop (i.e. start point, end point, step size), and provide the index and element value in the elements that are renamed.

It's worth mentioning that this convenience comes with the cost for contour control (i.e. start point, end point, step size), reverse iteration, break

whole loop capability , low performance impedance, and yes, even browser compatibility.

+2


source


each

expresses your intent: iteration and side-effect execution for each element. each

abstracts the iteration process: initialization and incrementing the counter, fetching by array index. This is what functional combinators do.

Your code snippet is a great example. Rewrite this in a functional style:

app.currentUser = collections.users.models.find(function (u) {
  return u.username === user.username;
});

      

find

clearly expresses your intent and abstracts the concept of iteration until you find an element that matches your predicate.

+1


source


You cannot naturally disconnect from the callback function forEach

or each

. However, there is a technology that many people use to opt out of this with a custom exception:

var BreakException = function(){};

try{
    list.forEach(function(el){
        if (meetCriteria(el)){
            throw BreakException; // Break from forEach
        }
    });
}
catch (e){
    // Catch break
    if (e != BreakException) 
        throw e; // If not a break, but other exceptions, raise it
}

// Carry on

      

The simple approach above creates an object BreakException

and lifts it up when you want to break out of the unbreakable loop. Catch this quirk BreakException

and continue with what your function is doing.

Remember, always check to see if a BreakException is thrown as you defined, as other possible exceptions (like TypeError, etc.) are also caught in this catch statement. Do not swallow it without checking.

+1


source







All Articles