我正在使用Node.js和Mongoose -试图在深层注释嵌套中找到特定的注释,其中带有递归函数和forEach。有没有办法停止Node.js forEach?正如我所理解的,forEach迭代都是一个函数,我不能只做break,只做return,但这不会停止forEach。

function recurs(comment) {
    comment.comments.forEach(function(elem) {

        recurs(elem);

        //if(...) break;

    });
}

当前回答

你不可能从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
})

如果希望返回true以break,则可以使用some()。

其他回答

forEach不会在返回时中断,有一些丑陋的解决方案来完成这项工作,但我建议不要使用它,而是尝试使用Array.prototype.some或Array.prototype.every

Var ar = [1,2,3,4,5]; ar.some(函数(项目、索引){ If (item == 3){ 返回true; } Console.log ("item is:"+item+" index is:"+ index); });

你不可能从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
})

如果希望返回true以break,则可以使用some()。

无法从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;
        }
    }
}

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

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

我们不用普通的回报吗?

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

它将从'recurs'函数返回。我这样使用它。虽然这不会从forEach中中断,而是从整个函数中中断,但在这个简单的示例中,它可能是有效的

数组中。forEach不能被打破,使用try…catch或hack方法,如Array。每个或数组。有些只会让你的代码更难理解。这个问题只有两种解决方案:

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.entries method. 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:

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