[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

如何在JavaScript中使用新的forEach方法实现这一点?我尝试过返回;,return false;和断裂。break崩溃,return只会继续迭代。


当前回答

引用Array.prototype.forEach()的MDN文档:

除此之外,无法停止或中断forEach()循环通过抛出异常。如果您需要这样的行为,.forEach()方法是错误的工具,请改用普通循环。如果要测试谓词的数组元素并需要布尔返回值,则可以改用every()或some()。

对于您的代码(在问题中),如@bobince所建议的,请改用Array.protocol.some()。它非常适合您的用例。

Array.pr原型.some()对数组中的每个元素执行一次回调函数,直到找到一个回调返回真值(当转换为布尔值时变为真)的元素。如果找到这样的元素,some()立即返回true。否则,some()返回false。回调仅对已赋值数组的索引调用;对于已删除或从未赋值的索引,不会调用它。

其他回答

没有内置的功能可以为Each进行破解。要中断执行,必须抛出某种异常。

var BreakException={};尝试{[1,2,3]对于每个(函数(el){控制台日志(el);如果(el==2)抛出BreakException;});}捕获(e){如果(e!==BreakException)抛出e;}

JavaScript异常并不漂亮。如果你真的需要打破传统的for循环,那么它可能更合适。

使用数组#some

而是使用Array#some:

[1,2,3]一些(函数(el){控制台日志(el);返回el==2;});

这之所以有效,是因为只要按数组顺序执行的任何回调返回true,就会立即返回true,从而缩短其余回调的执行。

有些,它的逆every(返回false时停止)和forEach都是ECMAScript第五版方法,需要在缺少它们的浏览器上添加到Array.prototype中。

使用数组#间隔

[1,2,3]每(v=>{如果(v>2){return false//“break”}控制台日志(v);return true//如果不中断,则必须返回true});

考虑使用jquery的each方法,因为它允许在回调函数中返回false:

$.each(function(e, i) { 
   if (i % 2) return false;
   console.log(e)
})

Lodash库还提供了takeWhile方法,可以与map/reduce/fold等链接:

var users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
];

_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']

// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']

// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']

// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []

为什么不尝试将函数包装在Promise中?

我提出这个问题的唯一原因是我在API中使用了一个函数,该函数的作用方式与forEach类似。我不希望它在找到值后继续迭代,我需要返回一些东西,所以我只需要解析Promise并以这种方式执行。

traverseTree(doc): Promise<any> {
  return new Promise<any>((resolve, reject) => {
    this.gridOptions.api.forEachNode((node, index) => {
    //the above function is the one I want to short circuit.
      if(node.data.id === doc.id) {
        return resolve(node);
      }
    });
  });
}

那么你所需要做的就是做一些事情,比如

this.traverseTree(doc).then((result) => {
   this.doSomething(result);
});

我上面的例子是在typescript中,只需忽略类型。逻辑应该有助于你“打破”你的循环。

这是一个for循环,但像forEach()一样在循环中维护对象引用,但可以中断。

var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
    if(el === 1) break;
}

我知道这不是正确的方式。这不是打破循环。这是一个Jugad让结果=真;[1,2,3]对于每个(函数(el){if(结果){控制台日志(el);如果(el==2){result=false;}}});