Node.js逐行执行异步操作

时间:2017-10-27 18:16:40

标签: javascript node.js asynchronous

我试图逐行读取流,并为每行执行一些异步处理。我遇到的问题是如何确定所有行的操作何时完成。我以为我可以使用readline“close”事件,但这似乎是在我开始完成“line”事件的异步操作之前很久才触发的。

以下是有问题的事件处理程序:

logReader.on("line", inputLine => {
    self._processLogLine(inputLine, () => {
        if (self.streamFinished) {
            completionCallback(err);
        }
    });
});

logReader.on("close", () => {
    self.streamFinished = true;
});

当流上的所有行处理完成时,应调用completionCallback方法。

我考虑过为已启动/已完成的行操作添加计数器,并在匹配时调用completionCallback,但这看起来很尴尬。

3 个答案:

答案 0 :(得分:1)

这是你可以做到的一种方法,基本上跟踪每一行的成功。我没有足够的代码来测试它......

const lineProcessing = [];

const doCompletion = () => {
  if (self.streamFinished && !lineProcessing.includes(false)) {
    // Not sure where 'err' comes from
    completionCallback(err);
  }
}

logReader.on("line", inputLine => {
  lineProcessing.push(false);
  let processingIndex = lineProcessing.length - 1;
  self._processLogLine(inputLine, () => {
    lineProcessing[processingIndex] = true;
    doCompletion();
  });
});

logReader.on("close", () => {
  self.streamFinished = true;
});

答案 1 :(得分:1)

在没有更多背景的情况下确定需要发生什么有点困难。但这是一个快速而有点肮脏的修复,应该适应您的情况。它展示了如何通过承诺实现这一目标:

let promises = []

logReader.on("line", inputLine => {
    promises.push(new Promise(resolve => {
        self._processLogLine(inputLine, resolve)
    })
})

logReader.on("close", () => {
    Promise.all(promises)
        .then(completionCallback)
})

基本上,只需创建一个承诺数组。当您知道所有承诺都已添加到阵列中时,请在其上调用Promise.all()

如果您使用此方法,则可能需要添加错误检查(rejectingcatching)。

答案 2 :(得分:0)

了解发电机。他们为你提供了一个方法来做一个" for"循环...当你完成后,你只需从生成器函数返回。

所以你可以有一个生成器来读取文件,以及一个使用生成器的函数,然后当循环结束时,调用你的回调。