views:

633

answers:

4

In this very contrived example, I have an array with 3 elements that I'm looping over using the .each() method.

 var vals = $w('foo bar baz'); 

 vals.each( function(val) {
    alert(val);

    if( val == 'bar' ) {
        //This exits function(val)
        //but still continues with the .each()
        return;
    }
  });

I can easily return out of the function being called by .each() if I need to.

My question is, how can I break out of the .each() loop from inside the function that .each() is calling?

+7  A: 
if( val == 'bar' ) {
    throw $break;
}

It's documented at the same page you linked. It's an exception specially handled by the each function. When thrown, it prevents your function from being called on further elements.

Matthew Flaschen
Doh! Looks like there's a "throw $continue" too.
Mark Biek
However, "throw $continue" is deprecated in favor of a simple return.
Joel Mueller
+2  A: 

Your are correct, and Prototype has created an object ($break) that can be thrown from the each-function to enable this functionality. According to the Prototype API docs:

Regular loops can be short-circuited in JavaScript using the break and continue statements. However, when using iterator functions, your code is outside of the loop scope: the looping code happens behind the scene.

In order to provide you with equivalent (albeit less optimal) functionality, Prototype provides two global exception objects, $break and $continue. Throwing these is equivalent to using the corresponding native statement in a vanilla loop. These exceptions are properly caught internally by the each method.

Also, note that the $continue object has been deprecated, and to simulate a continue-statement, use a vanilla return statement instead.

Code example:

var result = [];
$R(1,10).each(function(n) {
  if (0 == n % 2)
    return; // this equals continue
  if (n > 6)
    throw $break;
  result.push(n);
});
// result -> [1, 3, 5]

You can read more about the each-function here: http://www.prototypejs.org/api/enumerable/each

PatrikAkerstrand
As noted there, $continue is deprecated and rather pointless. You can just return.
Matthew Flaschen
You are correct. I was too quick. Corrected.
PatrikAkerstrand
A: 

Based on the documentation for .each() that you linked to, you should use a throw $break; statement, this should cause further iterations to cease.

Simply returning will cause the iterator to continue to the next one.

Peter
A: 

From that page you linked to, isn't the correct way

 if(val == 'bar')
 {
    throw $break;
 }

?

Oliver N.