我试图逐行读取流,并为每行执行一些异步处理。我遇到的问题是如何确定所有行的操作何时完成。我以为我可以使用readline“close”事件,但这似乎是在我开始完成“line”事件的异步操作之前很久才触发的。
以下是有问题的事件处理程序:
logReader.on("line", inputLine => {
self._processLogLine(inputLine, () => {
if (self.streamFinished) {
completionCallback(err);
}
});
});
logReader.on("close", () => {
self.streamFinished = true;
});
当流上的所有行处理完成时,应调用completionCallback方法。
我考虑过为已启动/已完成的行操作添加计数器,并在匹配时调用completionCallback,但这看起来很尴尬。
答案 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()
。
答案 2 :(得分:0)
了解发电机。他们为你提供了一个方法来做一个" for"循环...当你完成后,你只需从生成器函数返回。
所以你可以有一个生成器来读取文件,以及一个使用生成器的函数,然后当循环结束时,调用你的回调。