如何停止 Javascript forEach?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6260756/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:59:48  来源:igfitidea点击:

how to stop Javascript forEach?

javascriptecmascript-5

提问by kulebyashik

i'm playing with nodejs and mongoose — trying to find specific comment in deep comments nesting with recursive func and foreach within. Is there a way to stop nodejs forEach? As i understand every forEach iteration is a function and and i can't just do "break",only "return" but this won't stop foreach.

我正在使用 nodejs 和 mongoose - 试图在嵌套了递归 func 和 foreach 的深层注释中找到特定的注释。有没有办法停止 nodejs forEach?据我了解,每个 forEach 迭代都是一个函数,我不能只做“中断”,只能“返回”,但这不会停止 foreach。

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

回答by slezica

You can't break from a forEach. I can think of three ways to fake it, though.

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

1. The Ugly Way: pass a second argument to forEachto use as context, and store a boolean in there, then use an if. This looks awful.

1.丑陋的方式:将第二个参数传递forEach用作上下文,并在其中存储一个布尔值,然后使用一个if。这看起来很糟糕。

2. The Controversial Way: surround the whole thing in a try-catchblock and throw an exception when you want to break. This looks pretty bad and may affect performance, but can be encapsulated.

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

3. The Fun Way: use every().

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

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

You can use some()instead, if you'd rather return trueto break.

some()如果你想return true打破,你可以改用。

回答by Domenic

Breaking out of Array#forEachis not possible. (You can inspect the source code that implements it in Firefox on the linked page, to confirm this.)

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

Instead you should use a normal forloop:

相反,您应该使用普通for循环:

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

(or, if you want to be a little more clever about it and comment.comments[i]is always an object:)

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

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

回答by igor

In some cases Array.somewill probably fulfil the requirements.

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

回答by Mark Kahn

As others have pointed out, you can't cancel a forEachloop, but here's my solution:

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

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

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

Of course this doesn't actually break the loop, it just prevents code execution on all the elements following the "break"

当然,这实际上并没有中断循环,它只是阻止在“中断”之后的所有元素上执行代码

回答by Shrihari Balasubramani

I guess you want to use Array.prototype.findFind will break itself when it finds your specific value in the array.

我猜你想使用 Array.prototype。findFind 会在数组中找到您的特定值时自行中断。

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 }

回答by imal hasaranga perera

forEach does not break on return, there are ugly solutions to get this work but I suggest not to use it, instead try to use Array.prototype.someor Array.prototype.every

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

回答by exmaxx

You can use Lodash's forEachfunction if you don't mind using 3rd party libraries.

forEach如果您不介意使用 3rd 方库,您可以使用 Lodash 的功能。

Example:

例子:

var _ = require('lodash');

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

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

回答by Владимир

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

回答by Nicolas Bouvrette

Array.forEachcannot be broken and using try...catchor hacky methods such as Array.everyor Array.somewill only make your code harder to understand. There are only two solutions of this problem:

Array.forEach不能被破坏,使用try...catch或 hacky 方法,例如Array.everyArray.some只会使您的代码更难以理解。这个问题只有两种解决方案:

1) use a old forloop: this will be the most compatible solution but can be very hard to read when used often in large blocks of code:

1) 使用旧for循环:这将是最兼容的解决方案,但在大块代码中经常使用时可能很难阅读:

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) use the new ECMA6 (2015 specification) in cases where compatibility is not a problem. Note that even in 2016, only a few browsers and IDEs offer good support for this new specification. While this works for iterable objects (e.g. Arrays), if you want to use this on non-iterable objects, you will need to use the Object.entriesmethod. This method is scarcely available as of June 18th 2016 and even Chrome requires a special flag to enable it: chrome://flags/#enable-javascript-harmony. For Arrays, you won't need all this but compatibility remains a problem:

2) 在兼容性不成问题的情况下使用新的 ECMA6(2015 规范)。请注意,即使在 2016 年,也只有少数浏览器和 IDE 为这个新规范提供了良好的支持。虽然这适用于可迭代对象(例如数组),但如果您想在不可迭代对象上使用它,则需要使用该Object.entries方法。截至 2016 年 6 月 18 日,此方法几乎不可用,甚至 Chrome 也需要一个特殊标志来启用它:chrome://flags/#enable-javascript-harmony. 对于数组,您不需要所有这些,但兼容性仍然是一个问题:

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) A lot of people would agree that neither the first or second option are good candidates. Until option 2 becomes the new standard, most popular libraries such as AngularJS and jQuery offer their own loop methods which can be superior to anything available in JavaScript. Also for those who are not already using these big libraries and that are looking for lightweight options, solutions like thiscan be used and will almost be on par with ECMA6 while keeping compatibility with older browsers.

3) 很多人会同意第一种或第二种选择都不是好的候选人。在选项 2 成为新标准之前,大多数流行的库(例如 AngularJS 和 jQuery)都提供了自己的循环方法,这些方法可能优于 JavaScript 中可用的任何方法。同样对于那些还没有使用这些大型库并且正在寻找轻量级选项的人来说,可以使用这样的解决方案,并且几乎可以与 ECMA6 相提并论,同时保持与旧浏览器的兼容性。

回答by D G ANNOJIRAO

Below code will break the foreach loop once the condition is met, below is the sample example

一旦满足条件,下面的代码将中断 foreach 循环,下面是示例

    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;