ecmascript 5 - ¿cómo detener el forEach de Javascript?
Estoy jugando con Node.js y Mongoose — tratando de encontrar un comentario específico en un anidamiento profundo de comentarios con una función recursiva y forEach dentro. ¿Hay alguna manera de detener el forEach de Node.js? Según entiendo, cada iteración de forEach es una función y no puedo simplemente hacer break, solo return, pero esto no detendrá el forEach.
function recurs(comment) {
comment.comments.forEach(function(elem) {
recurs(elem);
//if(...) break;
});
}
Respuesta #1
No puedes usar break en un forEach. Sin embargo, puedo pensar en tres maneras de simularlo.
1. La forma fea: pasa un segundo argumento a forEach para usarlo como contexto, y almacena un valor booleano allí, luego usa un if. Esto se ve horrible.
2. La manera controvertida: rodea todo con un bloque try-catch y lanza una excepción cuando quieras interrumpir. Esto se ve bastante mal y puede afectar el rendimiento, pero se puede encapsular.
3. La forma divertida: usa every().
['a', 'b', 'c'].every(function(element, index) {
// Do your thing, then:
if (you_want_to_break) return false
else return true
})
Puedes usar some() en su lugar, si prefieres return true para detener.
Respuesta #2
Salir de Array#forEach no es posible. (Puede inspeccionar el código fuente que lo implementa en Firefox en la página enlazada, para confirmar esto.)
En su lugar, deberías usar un bucle for normal:
function recurs(comment) {
for (var i = 0; i < comment.comments.length; ++i) {
var subComment = comment.comments[i];
recurs(subComment);
if (...) {
break;
}
}
}
(o, si quieres ser un poco más ingenioso y comment.comments[i] siempre es un objeto:)
function recurs(comment) {
for (var i = 0, subComment; subComment = comment.comments[i]; ++i) {
recurs(subComment);
if (...) {
break;
}
}
}
Respuesta #3
forEach no se detiene con return, hay soluciones feas para que funcione, pero sugiero no usarlo; en su lugar, intenta usar Array.prototype.some o Array.prototype.every
var ar = [1,2,3,4,5];
ar.some(function(item,index){
if(item == 3){
return true;
}
console.log("item is :"+item+" index is : "+index);
});Respuesta #4
En algunos casos Array.some probablemente cumplirá los requisitos.
Respuesta #5
Como otros han señalado, no puedes cancelar un bucle forEach, pero aquí está mi solución:
ary.forEach(function loop(){
if(loop.stop){ return; }
if(condition){ loop.stop = true; }
});
Por supuesto, esto en realidad no rompe el bucle, solo evita la ejecución del código en todos los elementos que siguen al "break"
Respuesta #6
Supongo que quieres usar Array.prototype.find. Find se detendrá cuando encuentre tu valor específico en el arreglo.
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries));
// { name: 'cherries', quantity: 5 }
Respuesta #7
Puedes usar la función forEach de Lodash si no te importa usar bibliotecas de terceros.
Ejemplo :
var _ = require('lodash');
_.forEach(comments, function (comment) {
do_something_with(comment);
if (...) {
return false; // Exits the loop.
}
})
