Выход из цикла PrototypeJS .each()

В этом очень надуманном примере у меня есть массив с 3 элементами, которые я перебираю, используя .each() метод.

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;
    }
});

Я могу легко выйти из функции, вызываемой .each(), если мне нужно.

У меня вопрос: как выйти из цикла .each() внутри функции, которую вызывает .each()?


person Mark Biek    schedule 25.06.2009    source источник


Ответы (4)


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

Это задокументировано на той же странице, на которую вы ссылаетесь. Это исключение, специально обработанное каждой функцией. При броске он предотвращает вызов вашей функции для других элементов.

person Matthew Flaschen    schedule 25.06.2009
comment
Дох! Похоже, там тоже есть бросок $continue. - person Mark Biek; 25.06.2009
comment
Однако бросок $continue устарел в пользу простого возврата. - person Joel Mueller; 25.06.2009
comment
Я хочу отметить, что на новой странице документов сейчас нет этой информации - person llamerr; 19.04.2013

Вы правы, и Prototype создал объект ($break), который можно вызвать из каждой функции, чтобы включить эту функцию. Согласно документам Prototype API:

Обычные циклы можно сократить в JavaScript с помощью операторов break и continue. Однако при использовании функций итератора ваш код выходит за рамки цикла: циклический код происходит за сценой.

Чтобы предоставить вам эквивалентную (хотя и менее оптимальную) функциональность, Prototype предоставляет два глобальных объекта исключений, $break и $continue. Выброс их эквивалентен использованию соответствующего нативного оператора в ванильном цикле. Эти исключения должным образом перехватываются внутри каждого метода.

Кроме того, обратите внимание, что объект $continue устарел, и для имитации оператора continue используйте вместо него ванильный оператор return.

Пример кода:

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]

Подробнее о каждой функции можно прочитать здесь: http://www.prototypejs.org/api/enumerable/each

person PatrikAkerstrand    schedule 25.06.2009
comment
Как отмечено там, $continue устарела и довольно бессмысленна. Вы можете просто вернуться. - person Matthew Flaschen; 25.06.2009

Основываясь на документации для .each(), на которую вы ссылались, вы должны использовать оператор throw $break;, это должно привести к прекращению дальнейших итераций.

Простое возвращение приведет к тому, что итератор перейдет к следующему.

person Peter    schedule 25.06.2009

С той страницы, на которую вы ссылаетесь, это неправильный путь

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

?

person Oliver N.    schedule 25.06.2009