2

我有一个要使用https://github.com/caolan/async并行运行的任务列表。

我希望程序在第一个并行任务完成后继续(可能通过回调),而不是全部完成。所以我不认为天真

async.parallel([task1, task2], callback)

为我工作。

或者,我可以生成两个任务并取消不完整的任务,但我也无法弄清楚如何使用异步来做到这一点。

谢谢!-查理

4

2 回答 2

6

平行赛

您可以async通过返回一个error评估为true但实际上不是错误的值来启动最终回调。

我整理了一个-1用作错误代码的示例。在最后的回调中,我检查了该error值,如果不是,-1则它是一个实际错误。如果错误值是,-1那么我们将在results. 那时,我们只需要从results其他尚未完成的异步函数中删除额外的元素。

在下面的示例中,我使用request模块来拉取 html 页面,并使用underscore模块来过滤最终回调中的结果。

var request = require('request');
var _ = require('underscore');

exports.parallel = function(req, res) {
  async.parallel([
    /* Grab Google.jp */
    function(callback) {
      request("http://google.jp", function(err, response, body) {
        if(err) { console.log(err); callback(true); return; }
        callback(-1,"google.jp");
      });
    },
    /* Grab Google.com */
    function(callback) {
      request("http://google.com", function(err, response, body) {
        if(err) { console.log(err); callback(true); return; }
        callback(-1,"google.com");
      });
    }
    ],
    /* callback handler */
    function(err, results) {
      /* Actual error */
      if(err && err!=-1) {
        console.log(err);
        return;
      }
      /* First data */
      if(err===-1) {
        /*
         * async#parallel returns a list, one element per parallel function.
         * Functions that haven't finished yet are in the list as undefined.
         * use underscore to easily filter the one result.
         */
        var one = _.filter(results, function(x) {
          return (x===undefined ? false : true);
        })[0];
        console.log(results);
        console.log(one);
        res.send(one);
      }
    }
  );
};

剩余函数结果

当您设置async#parallel为这样工作时,您将无法访问其他异步函数的结果。如果您只对第一个响应的人感兴趣,那么这不是问题。但是,您将无法取消其他请求。这很可能不是问题,但可能是一个考虑因素。

于 2013-06-01T03:23:24.483 回答
1

async.parallel文档说:

如果任何函数将错误传递给其回调,则会立即使用错误值调用主回调。

因此,您可以从所有并行仿函数返回一个错误对象,第一个完成的函数会将您跳转到完成回调。甚至可能是您自己的特殊错误类,因此您可以区分实际错误和“嘿,我赢了”错误。

话虽如此,您仍然可以运行并行函数,可能等待回调完成或其他任何事情。也许您可以使用async.parallelLimit它来确保您不会并行执行太多任务?

说了这么多,通过尝试异步库中的另一种方法来执行此任务可能会更好地为您服务 - 启动并行任务然后让这些任务相互竞争可能不是最好的主意。

于 2013-06-01T03:24:11.487 回答