cursor.forEach()中的“continue”

时间:2013-08-26 21:00:04

标签: javascript mongodb foreach meteor

我正在使用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正常但是我很感兴趣,如果有类似的东西可以使用in forEach()。

7 个答案:

答案 0 :(得分:449)

forEach()的每次迭代都会调用您提供的函数。要在任何给定的迭代中停止进一步处理(并继续下一个项目),您只需在适当的位置从函数return

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

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

答案 1 :(得分:9)

在我看来,使用filter method来实现这一目标的最佳方法是因为它在forEach块中返回毫无意义;有关您的代码段的示例:

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

这会缩小elementsCollection的范围,只保留应处理的filtred元素。

答案 2 :(得分:4)

以下是使用for ofcontinue而非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();

});

答案 3 :(得分:1)

使用JavaScript short-circuit评估。如果el.shouldBeProcessed返回true,则doSomeLengthyOperation

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

答案 4 :(得分:1)

简单的答案是在 return 循环中放置一个 forEach 语句将为您完成@nnnnnn 所说的工作,

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

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

但如果你想深入回答这个问题,那就跟我在一起吧。

假设你不知道 forEach 循环的实现,那么看看下面 forEach 循环的实现,这正是 ECMA-262, 5th edition for {{ 1}} 循环。

来源 Array.prototype.forEach() - JavaScript | MDN

forEach

你真的不需要理解上面代码的每一行,因为我们感兴趣的是 if (!Array.prototype['forEach']) { Array.prototype.forEach = function(callback, thisArg) { if (this == null) { throw new TypeError('Array.prototype.forEach called on null or undefined'); } var T, k; // 1. Let O be the result of calling toObject() passing the // |this| value as the argument. var O = Object(this); // 2. Let lenValue be the result of calling the Get() internal // method of O with the argument "length". // 3. Let len be toUint32(lenValue). var len = O.length >>> 0; // 4. If isCallable(callback) is false, throw a TypeError exception. // See: https://es5.github.com/#x9.11 if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function'); } // 5. If thisArg was supplied, let T be thisArg; else let // T be undefined. if (arguments.length > 1) { T = thisArg; } // 6. Let k be 0 k = 0; // 7. Repeat, while k < len while (k < len) { var kValue; // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the HasProperty // internal method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then if (k in O) { // i. Let kValue be the result of calling the Get internal // method of O with argument Pk. kValue = O[k]; // ii. Call the Call internal method of callback with T as // the this value and argument list containing kValue, k, and O. callback.call(T, kValue, k, O); } // d. Increase k by 1. k++; } // 8. return undefined }; } 循环,

while

如果你注意到还有一个语句 while (k < len) { var kValue; // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the HasProperty // internal method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then if (k in O) { // i. Let kValue be the result of calling the Get internal // method of O with argument Pk. kValue = O[k]; // ii. Call the Call internal method of callback with T as // the this value and argument list containing kValue, k, and O. callback.call(T, kValue, k, O); } // d. Increase k by 1. k++; } ,我们对这里给 callback.call(T, KValue, K, O) 方法的参数不感兴趣,但我们真正感兴趣的是 call() 绑定,它是一个 callback,你在 javascript 中给你的 function 循环。请参阅 forEach 方法仅调用对象(javascript 函数),并使用 call 值和单独提供的参数调用它。

如果您不明白什么是调用,请查看 Function.prototype.Call() - JavaScript | MDN

如果在任何时候你的函数 this 在这种情况下返回,循环将像往常一样更新。循环不关心 callback 函数是否已经执行给它的每一步,如果控制权返回到循环,循环必须完成它的工作。每次循环更新时,callback 都会用一组新值调用,正如您所看到的,每次循环更新时 callback 都会发生变化,因此如果您在任何时候从函数返回,即 { {1}} 无论您在什么时候从函数返回,您都只是将控制权交给被调用的循环,如果您想在给定条件下跳过函数内部的某些操作,则只需将 return 语句放在前面那些你想跳过的语句。

这就是您在 T, KValue, K, O 循环内跳过迭代的方式。

答案 5 :(得分:0)

如果你使用经典的for循环并且不想使用continue,你可以在其中使用自执行函数并使用return来模仿{ {1}} 行为:

continue

输出:

for (let i = 0; i < 10; i++) {
    (() => {
        if (i > 5) return;
        console.log("no.", i)
    })();
}

console.log("exited for loop")

答案 6 :(得分:-3)

使用 continue 语句代替返回来跳过JS循环中的迭代。