web-dev-qa-db-fra.com

comment arrêter Javascript pour chaque

je joue avec nodejs et mongoose - j'essaie de trouver des commentaires spécifiques dans des commentaires profonds imbriqués avec func et foreach à l'intérieur. Existe-t-il un moyen d'arrêter nodejs pour chaque? Si je comprends bien, chaque itération de Chaque transaction est une fonction et je ne peux pas simplement "rompre", mais seulement "revenir", mais cela ne s’arrêtera pas.

function recurs(comment){
    comment.comments.forEach(function(elem){
        recurs(elem);
        //if(...) break;
    });
}
325
kulebyashik

Vous ne pouvez pas rompre avec un forEach. Je peux penser à trois façons de le simuler, cependant.

1. The Ugly Way : passez un deuxième argument à forEach à tilisez comme contexte , et stockez un booléen, puis utilisez un if . Cela semble affreux.

2. La manière controversée : entoure le tout d'un bloc try-catch et jette une exception lorsque vous voulez interrompre votre travail. Cela semble très mauvais et peut affecter les performances , mais peut être encapsulé.

3. La manière amusante : utilisez every().

['a', 'b', 'c'].every(function(element, index) {
  // Do your thing, then:
  if (you_want_to_break) return false
  else return true
})

Vous pouvez utiliser some() à la place, si vous préférez return true vous interrompre.

822
slezica

Sortir de Array # forEach n'est pas possible. (Vous pouvez vérifier le code source qui l'implémente dans Firefox sur la page liée.)

Au lieu de cela, vous devriez utiliser une boucle normale for:

function recurs(comment) {
    for (var i = 0; i < comment.comments.length; ++i) {
        var subComment = comment.comments[i];
        recurs(subComment);
        if (...) {
            break;
        }
    }
}

(ou si vous voulez être un peu plus intelligent et que comment.comments[i] est toujours un objet :)

function recurs(comment) {
    for (var i = 0, subComment; subComment = comment.comments[i]; ++i) {
        recurs(subComment);
        if (...) {
            break;
        }
    }
}
41
Domenic

Dans certains cas, Array.some satisfera probablement aux exigences.

33
igor

Comme d'autres l'ont fait remarquer, vous ne pouvez pas annuler une boucle forEach, mais voici ma solution:

ary.forEach(function loop(){
    if(loop.stop){ return; }

    if(condition){ loop.stop = true; }
});

Bien sûr, cela ne casse pas la boucle, cela empêche simplement l'exécution de code sur tous les éléments suivant le "break"

29
Mark Kahn

Je suppose que vous voulez utiliser Array.prototype . find Find se cassera quand il trouvera votre valeur spécifique dans le tableau.

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 }
13

forEach ne se casse pas au retour, il existe des solutions laides pour obtenir ce travail, mais je suggère de ne pas l'utiliser, essayez plutôt d'utiliser Array.prototype.some ou 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);
});
7

Vous pouvez utiliser la fonction forEach de Lodash si vous n’avez pas l’intention d’utiliser des bibliothèques tierces.

Exemple:

var _ = require('lodash');

_.forEach(comments, function (comment) {
    do_something_with(comment);

    if (...) {
        return false;     // Exits the loop.
    }
})
5
exmaxx

Array.forEach ne peut pas être cassé et l'utilisation de try...catch ou de méthodes plus simples telles que Array.every ou Array.some ne fera que rendre votre code plus difficile à comprendre. Il n'y a que deux solutions à ce problème:

1) utilisez une ancienne boucle for: ce sera la solution la plus compatible, mais elle peut être très difficile à lire si elle est utilisée souvent dans de gros blocs de code:

var testArray = ['a', 'b', 'c'];
for (var key = 0; key < testArray.length; key++) {
    var value = testArray[key];
    console.log(key); // This is the key;
    console.log(value); // This is the value;
}

2) utiliser le nouveau ECMA6 (spécification 2015) dans les cas où la compatibilité ne pose pas de problème. Notez que même en 2016, seuls quelques navigateurs et IDE offrent une prise en charge satisfaisante de cette nouvelle spécification. Bien que cela fonctionne pour les objets itérables (par exemple, les tableaux), si vous souhaitez l’utiliser sur des objets non-itérables, vous devrez utiliser la méthode Object.entries. Cette méthode est à peine disponible à partir du 18 juin 2016 et même Chrome nécessite un indicateur spécial pour l'activer: chrome://flags/#enable-javascript-harmony. Pour les tableaux, vous n’avez pas besoin de tout cela, mais la compatibilité reste un problème:

var testArray = ['a', 'b', 'c'];
for (let [key, value] of testArray.entries()) {
    console.log(key); // This is the key;
    console.log(value); // This is the value;
}

3) Beaucoup de gens conviendraient que ni la première ni la deuxième option ne sont de bons candidats. Jusqu'à ce que l'option 2 devienne la nouvelle norme, les bibliothèques les plus populaires telles que AngularJS et jQuery proposent leurs propres méthodes de boucle qui peuvent être supérieures à tout ce qui est disponible en JavaScript. De même, pour ceux qui n'utilisent pas déjà ces grandes bibliothèques et qui recherchent des options légères, des solutions telles que this peuvent être utilisées et seront presque au même niveau que ECMA6 tout en maintenant la compatibilité avec les navigateurs plus anciens.

3
Nicolas Bouvrette
    var f = "how to stop Javascript forEach?".split(' ');
    f.forEach(function (a,b){
        console.info(b+1);
        if (a == 'stop') {
            console.warn("\tposition: \'stop\'["+(b+1)+"] \r\n\tall length: " + (f.length)); 
            f.length = 0; //<--!!!
        }
    });
3
Владимир

Le code ci-dessous cassera la boucle foreach une fois la condition remplie, voici l'exemple de l'exemple

    var array = [1,2,3,4,5];
    var newArray = array.slice(0,array.length);
    array.forEach(function(item,index){
        //your breaking condition goes here example checking for value 2
        if(item == 2){
            array.length = array.indexOf(item);
        }

    })
    array = newArray;
1
D G ANNOJIRAO