如何组织一个async.waterfall调用循环

时间:2015-12-31 08:37:03

标签: javascript node.js async.js

如何组织async.waterfall循环调用以便每次迭代 只有在前一个完成后才开始

到目前为止,我有以下代码:

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) {

});

它的工作原理如下:

  • 有更多数据? (1)
  • 读取数据(1)
  • 有更多数据? (2)
  • 读取数据(2)
  • 得到数据(1)
  • 写数据(1)
  • ...

我理解为什么它按此顺序工作,在某些情况下这可能完全正确。但在我的具体情况下,我需要在前一个迭代完成后才开始新的迭代:

  • 有更多数据? (1)
  • 读取数据(1)
  • 得到数据(1)
  • 写数据(1)
  • 有更多数据? (2)
  • 读取数据(2)
  • ...

PS:我无法将所有数据读入数组,然后使用async.each处理数组。我都无法预测外部源有多少数据。

1 个答案:

答案 0 :(得分:1)

我没有使用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) {

});

直播示例(使用[{1}}和readData的填充程序):



writeData

// 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");
});
&#13;
&#13;
&#13;