简体   繁体   English

如何组织async.waterfall调用循环

[英]How to organize a loop of async.waterfall calls

How to organize a loop of async.waterfall calls so that every iteration starts only after the previous one is fully finished . 如何组织async.waterfall调用循环, 以便每次迭代仅在上一个迭代完全完成之后开始

So far I have the following code: 到目前为止,我有以下代码:

var hasMoreData = true;
async.whilst(function () {
  // * has more data?
  return hasMoreData;
},
function processData(callback1) {
  async.waterfall([
    function readDataFromSource(callback2) {
      // * read data
      readData(function readFinished(data, hasMore) {
        // * got data 
        hasMoreData = hasMore;
        callback2(null, data);
      });
    }, 
    function writeDataToDest(data, callback2) {
      // * write data
      writeData(data, function writeFinished() {
        callback2();
      });
    },
  ], function (err) {
    callback1(err);
  });
},
function finished(err) {

});

It works like this: 它是这样的:

  • has more data ? 有更多数据? (1) (1)
  • read data (1) 读取数据(1)
  • has more data ? 有更多数据? (2) (2)
  • read data (2) 读取数据(2)
  • got data (1) 得到了数据(1)
  • write data (1) 写数据(1)
  • ... ...

I understand why it works in this order , and this may be totally correct in some cases. 我了解为什么它按此顺序工作 ,在某些情况下这可能是完全正确的。 But in my specific case I need to start a new iteration only after the previous one is finished: 但是在我的特定情况下,仅在上一个迭代完成后才需要开始新的迭代:

  • has more data ? 有更多数据? (1) (1)
  • read data (1) 读取数据(1)
  • got data (1) 得到了数据(1)
  • write data (1) 写数据(1)
  • has more data ? 有更多数据? (2) (2)
  • read data (2) 读取数据(2)
  • ... ...

PS: I can't read all the data into array and then process the array with async.each, for example. PS:例如,我无法将所有数据读入数组,然后使用async.each处理该数组。 Neither I can predict how much data the external source has. 我也无法预测外部源有多少数据。

I don't use async , but just looking at the code and description and API docs, it seems like this does what you want, not using waterfall at all: 我不使用async ,而是仅查看代码,描述和API文档,看来这确实可以满足您的要求,根本不使用waterfall

var hasMoreData = true;
async.whilst(function () {
  // * has more data?
  return hasMoreData;
},
function processData(callback1) {
  // * read data
  // blocking i/o operation
  readData(function readFinished(data, hasMore) {
    // * got data
    hasMoreData = hasMore;
    // * write data
    // blocking i/o operation
    writeData(data, function writeFinished() {
      callback1();
    });
  });
},
function finished(err) {

});

Live Example (using shims for readData and writeData ): 实时示例 (将垫片用于readDatawriteData ):

 // Shims var datacount = 0; function readData(callback) { // since you said "blocking", busy-wait for a quarter second var done = Date.now() + 250; while (done > Date.now()) { } // but calls like this are almost always async, so we'll complete async ++datacount; setTimeout(function() { callback(datacount, datacount < 3); }, 0); } function writeData(data, callback) { // since you said "blocking", busy-wait for a quarter second var done = Date.now() + 250; while (done > Date.now()) { } // but calls like this are almost always async, so we'll complete async setTimeout(function() { callback(); }, 0); } // The code var hasMoreData = true; async.whilst(function() { // * has more data? snippet.log("has more data?"); return hasMoreData; }, function processData(callback1) { // * read data snippet.log("read data"); // blocking i/o operation readData(function readFinished(data, hasMore) { // * got data snippet.log("got data: " + data + " (more? " + hasMore + ")"); hasMoreData = hasMore; // * write data snippet.log("write data"); // blocking i/o operation writeData(data, function writeFinished() { callback1(); }); }); }, function finished(err) { snippet.log("finished"); }); 
 <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/async/1.5.0/async.min.js"></script> 

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

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