跳出嵌套的JavaScript异步循环,但继续主循环。

3
我有一个由对象组成的数组,名为recipesArray。
recipesArray = [  [{name = "the recipe name", url = "http://recipeurl.com"},
                   {name = "the other neame", url = "http://adifferenturl.com"},
                   {name = "another recipe", url = "http://anotherurl.com"}],

                   [{name = "the recipe name", url = "http://recipeurl.com"},
                   {name = "the other neame", url = "http://adifferenturl.com"},
                   {name = "another recipe", url = "http://anotherurl.com"}],

                   [{name = "the recipe name", url = "http://recipeurl.com"},
                   {name = "the other neame", url = "http://adifferenturl.com"},
                   {name = "another recipe", url = "http://anotherurl.com"}] ]

我希望能够跳出这个嵌套的async.each循环,但是继续主要的async.each循环。

// main async.each
async.each(recipes, function(subArray, callback1) {
   // nested async.each
   async.each(subArray, function(theCurrentRecipe, callback2) {
      checkHREFS(theCurrentRecipe, function(thisRecipe) {
         if ('i have a conditional here') {
            // break out of this nested async.each, 
            // but continue the main async.each.
         } else {
            // continue
         }
         callback2();
      });
   }, callback1);
}, function(err) {
if (err) {
   return console.error(err);

   // success, all recipes iterated
});
2个回答

7

一种可能的方法是修改内部each()的最终回调,检查一个带有特殊属性的错误对象,该属性指示您早期退出且这不是真正的错误。然后在您的条件语句中,将带有该属性设置的错误对象传递给回调函数。

例如:

// main async.each
async.each(recipes, function(subArray, callback1) {
  // nested async.each
  async.each(subArray, function(theCurrentRecipe, callback2) {
    checkHREFS(theCurrentRecipe, function(thisRecipe) {
      if ('i have a conditional here') {
        // break out of this nested async.each, 
        // but continue the main async.each.
        var fakeErr = new Error();
        fakeErr.break = true;
        return callback2(fakeErr);
      }
      // continue
      callback2();
    });
  }, function(err) {
    if (err && err.break)
      callback1();
    else
      callback1(err);
  });
}, function(err) {
  if (err)
    return console.error(err);

  // success, all recipes iterated
});

虽然我仍在思考是否有比伪造错误更好的方法。 - Joel
目前我并没有使用 async 模块,实际上我在需要提前中断 async 模块方法时会使用这种模式。 - mscdex

1
// inner async.each (simplificated)
  async.each(subArray, function(theCurrentRecipe, callback2) {
    checkHREFS(theCurrentRecipe, function(thisRecipe) {
      if ('i have a conditional here') {
        // going to break out of this nested async.each
        return callback2({flag:true}); // It doesn't have to be an "new Error()" ;-)
      }
      // continue
      callback2();
    });
  }, function(msg) {
    if (msg && msg.flag) // Here CHECK THE FLAG
      callback1(); // all good!... we brake out of the loop!
    else
      callback1(msg); // process possible ERROR.
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接