From: Jorge on
On Mar 4, 3:26 pm, Stevo <n...(a)mail.invalid> wrote:
> Jorge wrote:
> > Is it possible ?
>
> Does break; not work ?

No, it throws an "invalid break"...
--
Jorge
From: Jorge on
On Mar 4, 3:54 pm, kangax <kan...(a)gmail.com> wrote:
> On 3/4/10 9:14 AM, Jorge wrote:
>
> > Is it possible ?
>
> `throw` will take you out of it. But then you might want a wrapper to
> handle it gracefully, and it all adds complexity of course.
>
> Here's an untested example:
>
> Array.prototype.each = (function(){
>    var stopIterationError = { };
>    return function(callback, thisValue) {
>      try {
>        this.forEach(function() {
>          if (callback.apply(thisValue, arguments) === false) {
>            throw stopIterationError;
>          }
>        });
>      }
>      catch(err) {
>        if (err !== stopIterationError) {
>          throw err;
>        }
>      }
>    };
>
> })();
>
> [1,2,3].each(function(item, index){
>    console.log(arguments);
>    if (index == 1) return false;
>
> });
>
> (Maybe you can replace that `stopIterationError` object with an object
> that inherits from `Error`; I'm not sure how cross-browser it would be)

Great. I wanted to break out from a catch. So I just need to put the
try wrapping the forEach, right ?

e.g.

var n=0;
try {
[1,2,3].forEach(function (value, index, object){
n++;
throw({});
});
} catch (e) {
console.log("Broke out @#"+ n);
}

?
Thanks,
--
Jorge.
From: Antony Scriven on
On Mar 4, 2:54 pm, kangax wrote:

> On 3/4/10 9:14 AM, Jorge wrote:
>
> > Is it possible [to break out of a forEach()]?
>
> `throw` will take you out of it. But then you might want
> a wrapper to handle it gracefully, and it all adds
> complexity of course.
>
> Here's an untested example:
>
> Array.prototype.each = (function(){
> var stopIterationError = { };
> return function(callback, thisValue) {
> try {
> this.forEach(function() {
> if (callback.apply(thisValue, arguments) === false) {
> throw stopIterationError;
> }
> });
> }
> catch(err) {
> if (err !== stopIterationError) {
> throw err;
> }
> }
> };
>
> })();
>
> [1,2,3].each(function(item, index){
> console.log(arguments);
> if (index == 1) return false;
>
> });

Does it need to be that complex?

var LIB = (function(){
Array.prototype.each = function(func, thisvalue){
try{
this.forEach(func, thisvalue);
}catch(e){
if(e !== LIB.stopEach){
throw e;
}
}
};
return {stopEach: {}};
}());

[1,2,3].each(function(item, index){
console.log(arguments);
if (index == 1) throw LIB.stopEach;
});

IME this construct doesn't occur very often so I also think
it helps to make the termination statement as obvious as
possible. --Antony
From: Jorge on
On Mar 4, 3:55 pm, Stefan Weiss <krewech...(a)gmail.com> wrote:
> On 04/03/10 15:14, Jorge wrote:
>
> > Is it possible ?
>
> AFAIK, it isn't. With iterators, you could at least throw a
> StopIteration, but I don't see any possibility with forEach().
>
> You could try using something along the lines of:
>
>     function walk (list, fun, context) {
>         var i = 0,
>             len = list.length,
>             rv;
>         for (; i < len; i++) {
>             if (i in list) {
>                 rv = fun.call(context, list[i], i);
>                 if (rv !== undefined) {
>                     return rv;
>                 }
>             }
>         }
>     }
>
> This works similar to Array.prototype.forEach, but will stop looping if
> the function "fun" returns anything other than undefined. It can also
> double as a filter to find the first array element matching your
> criteria. Adding this to Array.prototype is straight-forward, but if
> it's stand-alone, you can use it to iterate over node lists (for
> example) as well as arrays.

Thanks, Stefan. I think I'm going to throw in order to break out.
Cheers,
--
Jorge.
From: Antony Scriven on
On Mar 4, 3:59pm, Jorge wrote:

> On Mar 4, 3:54pm, kangax <kan...(a)gmail.com> wrote:
>
> [...]
>
> Great. I wanted to break out from a catch. So I just need to put
the
> try wrapping the forEach, right ?
>
> e.g.
>
> var n=0;
> try {
> [1,2,3].forEach(function (value, index, object){
> n++;
> throw({});
> });} catch (e) {
>
> console.log("Broke out @#"+ n);
>
> }

This would be my preferred overall form since it's intention
is obvious to the reader. However, if your real code is
anything more complex than n++ then you could potentially be
masking any other exceptions that get thrown. Make sure you
examine the exception object and check it's the right one as
Kangax did originally. --Antony