使用异步

时间:2016-09-23 19:01:24

标签: javascript node.js async.js highland.js

我正在使用highland.js使用流处理文件来读取两个分隔符之间的内容。我还使用async.js按顺序运行一系列http请求。

理想情况下,我希望将输出x作为第一个函数从高地传递到async系列(链),以便为从流中提取的每个块执行HTTP请求。

这可能吗?如果是这样,怎么能实现呢?

var async = require('async');
var _ = require('highland');


_(fs.createReadStream(files[0], { encoding: 'utf8' }))
        .splitBy('-----BEGIN-----\n')
        .splitBy('\n-----END-----\n')
        .filter(chunk => chunk !== '')
        .each(function (x) {
        }).done(function () {

    async.series([
        function(callback) {
            setTimeout(function() {
                console.log('Task 1');
                callback(null, 1);
            }, 300);
        },
        function(callback) {
            setTimeout(function() {
                console.log('Task 2');
                callback(null, 2);
            }, 200);
        },
    ], function(error, results) {
        console.log(results);
    });

});;

1 个答案:

答案 0 :(得分:1)

您可以删除对eachdone的来电。过滤后,您可以使用.toArray(callback)进行跟进。回调传递一个包含高地结果的数组。你可能会像这样重构

var Q = require('q');
var _ = require('highland');


_(fs.createReadStream(files[0], { encoding: 'utf8' }))
        .splitBy('-----BEGIN-----\n')
        .splitBy('\n-----END-----\n')
        .filter(chunk => chunk !== '')
        .each(asyncTasks);

function asyncTasks(x) { // here, x will be each of the results from highland
    async.series([
      // do something with x results
        function(callback) {
          console.log('Task 1');
          callback(null, 1);
        },
        // do something else with x results
        function(callback) {
          console.log('Task 2');
          callback(null, 2);
        },
    ], function(error, results) {
        console.log(results);
    });
}

heretoArray文档的链接。 toArray消费流,就像done一样。如果您有任何问题,请告诉我。

虽然老实说,我认为你最好不要使用promises。虽然它的一部分只是个人偏好,但部分原因是它使代码更具可读性。从what I've read开始,async比promises更高效,但关于promises的好处是你可以将结果从一个函数传递给下一个函数。因此,在您的示例中,您可以在第一部分中对x执行一些操作,然后将修改后的结果传递给下一个函数,以及下一个函数,依此类推。当您使用async.series时,您可以通过致电callback(null, result)来完成每项功能,但是当您获得所有功能时,您将无法获得结果,直到您完成系列的最后所有对callback的调用的结果。现在,您始终可以将结果保存到async.series之外的某个变量,但这会使您的代码变得更加混乱。如果你想用promises重写它,它看起来如下。我在这里使用q,但它只是您可以使用的许多promise库之一。

    var async = require('async');
    var _ = require('highland');


    _(fs.createReadStream(files[0], { encoding: 'utf8' }))
            .splitBy('-----BEGIN-----\n')
            .splitBy('\n-----END-----\n')
            .filter(chunk => chunk !== '')
            .each(asyncTasks);

    function asyncTasks(x) { // here, x will be an array of the results from highland
      return asyncTask1(x)
              .then(asyncTask2)
              .then(asyncTask3)
    }

    function asyncTask1(x) {
      var deferred = Q.defer();

      // do some stuff

      if (// some error condition) {
        deferred.reject();
      } else {
        deferred.resolve(x); // or pass along some modified version of x
      }

      return deferred.promise;
    }

    function asyncTask2(x) {
      // same structure as above
    }

    function asyncTask3(x) {
      // same structure as above
    }

现在,一些异步API已经开始返回promises,除了接受回调,或者有时代替。所以舒服一点是件好事。承诺是非常有用的。您可以详细了解他们herehere

相关问题