简体   繁体   English

使用异步处理高地流块

[英]processing highland stream chunks using async

I'm using highland.js to process a file using a stream to read the contents between two delimiters.我正在使用highland.js使用流处理文件以读取两个分隔符之间的内容。 I'm also using async.js to run a series of http requests in sequence.我还使用async.js按顺序运行一系列 http 请求。

Ideally I would like to pass the output x from highland as the first function to the async series (chain) so that the HTTP requests get executed for each chunk extracted from the stream.理想情况下,我想将 highland 的输出x作为第一个函数传递给async系列(链),以便为从流中提取的每个块执行 HTTP 请求。

Is this possible?这可能吗? If so, how can this be achieved?如果是这样,如何实现?

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);
    });

});;

You can get rid of the calls to each and done .您可以摆脱对eachdone的调用。 After filtering, you can follow it up with .toArray(callback) .过滤后,您可以使用.toArray(callback)跟进。 The callback is passed an array that contains the results from highland.回调被传递一个包含高地结果的数组。 You might refactor like this你可能像这样重构

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);
    });
}

here is a link to the documentation for toArray .toArray文档的链接。 toArray consumes the stream, just as done also does. toArray消耗流,就像done一样。 Let me know if you have any questions.如果您有任何问题,请告诉我。

Although honestly, I think you would be better off using promises instead.虽然老实说,我认为你最好使用承诺。 Although part of it is just personal preferrence, partly because it makes the code more readable.虽然部分原因只是个人喜好,部分原因是它使代码更具可读性。 From what I've read , async is more performant than promises, but the nice part about promises is that you can pass the results from one function to the next.我读过的内容来看,异步比承诺更高效,但承诺的好处在于您可以将结果从一个函数传递到下一个函数。 So in your example, you could do some stuff to x in the first part, and then pass your modified result to the next function, and the next function, and so on.所以在你的例子中,你可以在第一部分对x做一些事情,然后将修改后的结果传递给下一个函数,下一个函数,依此类推。 Where when you're using async.series , you finish each function by calling callback(null, result) , and you don't get the results until you finish at the very end of the series when you get all the results from all of the calls to callback .当您使用async.series ,您通过调用callback(null, result)完成每个函数,并且直到您在系列的最后完成时才获得结果,当您获得所有结果时对callback Now, you could always save your results to some variable outside of async.series, but that would make your code messier.现在,您始终可以将结果保存到 async.series 之外的某个变量中,但这会使您的代码更加混乱。 If you wanted to re-write it with promises, it would look as follows.如果你想用 Promise 重写它,它看起来如下。 I am using q here, but it is just one of many promise libraries you could use.我在这里使用q ,但它只是您可以使用的众多承诺库之一。

    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
    }

Some asynchronous APIs these days have started to return promises, in addition to accepting callback, or sometimes in place of.这几天一些异步API已经开始返回promise了,除了接受回调,有时还可以代替。 So it would be a good thing to get comfortable with.所以适应起来会是一件好事。 Promises are super useful. Promise 非常有用。 You can read more about them here and here .您可以在此处此处阅读有关它们的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM