如何停止Javascript forEach?

kul*_*hik 332 javascript ecmascript-5

我正在玩nodejs和mongoose - 尝试在深层注释中找到特定注释,并使用递归函数和foreach进行嵌套.有没有办法阻止nodejs forEach?据我所知,每个forEach迭代都是一个函数而且我不能只做"休息",只能"返回",但这不会阻止foreach.

function recurs(comment){
    comment.comments.forEach(function(elem){
        recurs(elem);
        //if(...) break;
    });
}
Run Code Online (Sandbox Code Playgroud)

sle*_*ica 844

你不能打破forEach.不过,我可以想到三种方法来伪造它.

1.丑陋的方式:传递给第二个参数forEach,以如上下文中使用,并且存储一个布尔在那里,然后使用if.这看起来很糟糕.

2.有争议的方式:将整个事物包围在一个try-catch区块中,并在想要破坏时抛出异常.这看起来很糟糕,可能会影响性能,但可以封装.

3.有趣的方式:使用 every().

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

some()相反,你可以使用,如果你想要return true打破.

  • +1,虽然当你想打破时,使用`some()`和`return true`听起来更自然. (48认同)
  • 或者更优雅的是,在循环中放置`return!you_want_to_break`而不是if..else块.保存两行.:-) (21认同)
  • 除了IE7和8之外,每个人都支持`(我不得不查阅,所以我想分享) (14认同)
  • 应该有4号.美丽的方式:使用`some()` (5认同)
  • 不幸的是,使用every()或some()不会解决您希望打破特定值并返回它的情况.ECMAScript2015新作...的(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)可以帮助的那部分,但缺点是,这种解决方案可能会导致旧浏览器出现更多问题.如果您愿意完全改变路线并使用不同的更通用的方法,这样的解决方案(https://github.com/nbouvrette/forEach)可以帮助您,甚至可能解决其他问题. (5认同)

Dom*_*nic 44

打破Array#forEach是不可能的.(您可以在链接页面上检查在Firefox中实现它的源代码,以确认这一点.)

相反,你应该使用一个正常的for循环:

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

(或者,如果你想要更聪明一点,并且comment.comments[i]总是一个对象:)

function recurs(comment) {
    for (var i = 0, subComment; subComment = comment.comments[i]; ++i) {
        recurs(subComment);
        if (...) {
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 肯定是,但是使用异常来控制程序流是一个不好的坏习惯 (5认同)

igo*_*gor 33

在某些情况下,Array.some可能会满足要求.


Mar*_*ahn 29

正如其他人指出的那样,你无法取消forEach循环,但这是我的解决方案:

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

    if(condition){ loop.stop = true; }
});
Run Code Online (Sandbox Code Playgroud)

当然这实际上并没有打破循环,它只是阻止了"break"之后所有元素的代码执行

  • 我不认为这个解决方案是个好主意.想象你循环10000个元素,你的条件停在第二个元素,然后你将做任何不必要的迭代9998次.最好的方法是使用`some`或`every`. (9认同)
  • @PedroFerreira我的论点是有效的.我不是在冒犯任何人.我们需要批评我们的代码以使其更好.我宁愿阅读其他实现并帮助他们改进它而不是重新发明轮子. (3认同)
  • 巧妙地使用命名函数表达式 (2认同)

Shr*_*ani 15

我想你想使用Array.prototype.发现 查找时,它在阵列中找到您的具体价值将打破本身.

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 }
Run Code Online (Sandbox Code Playgroud)


ima*_*era 9

forEach不会在返回时破坏,有很难实现这项工作的解决方案,但我建议不要使用它,而是尝试使用Array.prototype.someArray.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);
});
Run Code Online (Sandbox Code Playgroud)


Вла*_*мир 7

    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; //<--!!!
        }
    });
Run Code Online (Sandbox Code Playgroud)


exm*_*axx 5

forEach如果您不介意使用第三方库,可以使用Lodash的功能.

例:

var _ = require('lodash');

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

    if (...) {
        return false;     // Exits the loop.
    }
})
Run Code Online (Sandbox Code Playgroud)