Búsqueda de sitios web

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

Artículos relacionados