簡體   English   中英

使用異步處理高地流塊

[英]processing highland stream chunks using async

我正在使用highland.js使用流處理文件以讀取兩個分隔符之間的內容。 我還使用async.js按順序運行一系列 http 請求。

理想情況下,我想將 highland 的輸出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);
    });

});;

您可以擺脫對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);
    });
}

toArray文檔的鏈接。 toArray消耗流,就像done一樣。 如果您有任何問題,請告訴我。

雖然老實說,我認為你最好使用承諾。 雖然部分原因只是個人喜好,部分原因是它使代碼更具可讀性。 我讀過的內容來看,異步比承諾更高效,但承諾的好處在於您可以將結果從一個函數傳遞到下一個函數。 所以在你的例子中,你可以在第一部分對x做一些事情,然后將修改后的結果傳遞給下一個函數,下一個函數,依此類推。 當您使用async.series ,您通過調用callback(null, result)完成每個函數,並且直到您在系列的最后完成時才獲得結果,當您獲得所有結果時對callback 現在,您始終可以將結果保存到 async.series 之外的某個變量中,但這會使您的代碼更加混亂。 如果你想用 Promise 重寫它,它看起來如下。 我在這里使用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
    }

這幾天一些異步API已經開始返回promise了,除了接受回調,有時還可以代替。 所以適應起來會是一件好事。 Promise 非常有用。 您可以在此處此處閱讀有關它們的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM