如何中断 async.js 的 each 循环?

11

嗨,我正在使用node.js的async模块异步实现for循环。

我的问题是:如何中断循环执行并退出循环?我尝试了returnreturn false但没有成功。

这是示例代码:

async.until( 

    function() { return goal; },

    function(callback) {

        async.each(_rules, 

            function(rule,callback) {

                var outcome = true;
                .... some code ....
                if(changes){ 
                      console.log("hi");
                      return false;// HERE I NEED TO BREAK
                } 
                else
                callback();

            }, 

            function(err){  }
        );

        if (!changes || session.process)                
            goal = true;

        callback();
    },

    function(err){ callback(session); }     
);

3
你可以通过在回调函数的第一个参数中发送某些内容来使程序终止(async 会将其解释为“错误”并停止循环)。将其设置为一个已知的值(一个真值),以便在最终的回调函数中进行检查,确认是因为终止而不是因为错误。 - Chad
你能告诉我如何在代码中的return false;位置调用callback(1)并且中断它吗? - Mithun Satheesh
如果您在所有路径中都不调用回调函数,那么循环将永远不会“结束”。如果有一条路径没有调用回调函数,则您的操作是错误的。这是异步的,您的返回值无效。 - Chad
3个回答

7
async.until 会反复调用函数直到测试返回 true。因此,测试必须返回 true 才能退出循环。这与 async.whilst 正好相反,后者在 test 求值为 true 时重复运行。 async.each 并行调用函数,因此它返回什么并不重要。它不是一个可以打破的循环,而是迭代器循环数组。停止使用 async.each 的条件应该在 async.until 的测试中,并且你应该自己遍历规则。

5

实际上,并不存在像“循环”那样的东西需要打破。你集合中的所有项都是并行使用的。

唯一打破“循环”的方法是通过错误参数调用回调函数。因为没有其他可以阻止你将其他内容放在那里,所以你可以对它进行一些修改。

从文档中可以得知:

请注意,由于此函数将迭代器并行应用于每个项目,因此无法保证迭代器函数将按顺序完成。

即使您返回了错误,仍然可能有几个未完成的请求,因此您真的希望限制一次使用的物品数量。要限制未完成请求的数量,您可以使用eachSeries或eachLimit。

例如:

    async.each(_rules, 
        function(rule,callback) {
            if(changes){                       
                  return callback({ data: 'hi'}); // stop
            } 
            ...
            if(realerror){
               return callback({ error: realerror}); // stop with an error
            }
            callback(); // continue
        }, 

        function(result){
          if(!result){
            return othercallback('no results');
          }
          // check if we have a real error:
          if(result.error){
            return othercallback(result.error);
          }
          return othercallback(null, result.data);
        }
    );

提示:如果您不使用异步,请使用underscore


你能告诉我怎么做吗?我不能在代码中所示的return false;行的位置调用callback(1)并终止它。 - Mithun Satheesh
@mithunsatheesh 简短回答:你必须这样做,而且是可以的。 - Chad
1
不要返回false,而是执行“return callback({data:false})”,并在最终回调函数中检查第一个参数。 - AndyD
并没有直接解决我的问题,但激发了我尝试不同的方法。 - Jujhar Singh

0

你还有 async.detect

返回通过异步真值测试的coll中的第一个值。迭代器并行应用,意味着第一个返回true的迭代器将使用该结果触发detect回调。

// asynchronous function that checks if a file exists
function fileExists(file, callback) {
   fs.access(file, fs.constants.F_OK, (err) => {
       callback(null, !err);
   });
}

async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists,
   function(err, result) {
       console.log(result);
       // dir1/file1.txt
       // result now equals the first file in the list that exists
   }
);


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