我正在使用meteor.js和MongoDB构建一个应用程序,我有一个关于cursor.forEach()的问题。 我想在每次forEach迭代的开始检查一些条件,然后跳过元素,如果我不需要对它进行操作,这样我可以节省一些时间。

这是我的代码:

// Fetch all objects in SomeElements collection
var elementsCollection = SomeElements.find();
elementsCollection.forEach(function(element){
  if (element.shouldBeProcessed == false){
    // Here I would like to continue to the next element if this one 
    // doesn't have to be processed
  }else{
    // This part should be avoided if not neccessary
    doSomeLengthyOperation();
  }
});

我知道我可以使用cursor.find().fetch()将光标转向数组,然后使用常规for循环迭代元素,并正常使用continue和break,但我感兴趣的是,如果在forEach()中使用类似的东西。


当前回答

下面是一个用for of和continue代替forEach的解决方案:


let elementsCollection = SomeElements.find();

for (let el of elementsCollection) {

    // continue will exit out of the current 
    // iteration and continue on to the next
    if (!el.shouldBeProcessed){
        continue;
    }

    doSomeLengthyOperation();

});

如果你需要在循环中使用在forEach中不起作用的异步函数,这可能会更有用一些。例如:


(async fuction(){

for (let el of elementsCollection) {

    if (!el.shouldBeProcessed){
        continue;
    }

    let res;

    try {
        res = await doSomeLengthyAsyncOperation();
    } catch (err) {
        return Promise.reject(err)
    }

});

})()

其他回答

forEach()的每次迭代都将调用您提供的函数。为了在任何给定的迭代中停止进一步的处理(并继续下一项),你只需要在适当的点从函数返回:

elementsCollection.forEach(function(element){
  if (!element.shouldBeProcessed)
    return; // stop processing this iteration

  // This part will be avoided if not neccessary
  doSomeLengthyOperation();
});

在我看来,实现这一点的最佳方法是使用filter方法,因为在forEach块中返回是没有意义的;在你的代码片段中有一个例子:

// Fetch all objects in SomeElements collection
var elementsCollection = SomeElements.find();
elementsCollection
.filter(function(element) {
  return element.shouldBeProcessed;
})
.forEach(function(element){
  doSomeLengthyOperation();
});

这将缩小您的elementsCollection,只保留应该处理的过滤元素。

下面是一个用for of和continue代替forEach的解决方案:


let elementsCollection = SomeElements.find();

for (let el of elementsCollection) {

    // continue will exit out of the current 
    // iteration and continue on to the next
    if (!el.shouldBeProcessed){
        continue;
    }

    doSomeLengthyOperation();

});

如果你需要在循环中使用在forEach中不起作用的异步函数,这可能会更有用一些。例如:


(async fuction(){

for (let el of elementsCollection) {

    if (!el.shouldBeProcessed){
        continue;
    }

    let res;

    try {
        res = await doSomeLengthyAsyncOperation();
    } catch (err) {
        return Promise.reject(err)
    }

});

})()

利用javascript进行短路计算。如果埃尔。shouldBeProcessed返回true, doSomeLengthyOperation

elementsCollection.forEach( el => 
  el.shouldBeProcessed && doSomeLengthyOperation()
);

使用continue语句而不是return来跳过JS循环中的迭代。