我为内置在nodejs中的readlines模块构建了一个简单的异步实现,它只是基于事件的模块本身的包装。代码如下;
const readline = require('readline');
module.exports = {
createInterface: args => {
let self = {
interface: readline.createInterface(args),
readLine: () => new Promise((succ, fail) => {
if (self.interface === null) {
succ(null);
} else {
self.interface.once('line', succ);
}
}),
hasLine: () => self.interface !== null
};
self.interface.on('close', () => {
self.interface = null;
});
return self;
}
}
理想情况下,我会在这样的代码中使用它;
const readline = require("./async-readline");
let filename = "bar.txt";
let linereader = readline.createInterface({
input: fs.createReadStream(filename)
});
let lines = 0;
while (linereader.hasLine()) {
let line = await linereader.readLine();
lines++;
console.log(lines);
}
console.log("Finished");
但是,我已经观察到了这种异步包装器的某些不稳定和意外行为。一方面,它无法识别文件何时结束,而仅在到达最后一行时挂起,从不打印“完成”。最重要的是,当输入文件很大(例如几千行)时,它总是偏离几行,并且在暂停之前无法成功读取完整的文件。在2000+行文件中,它最多可能偏离20-40行。如果将打印语句放入.on('close'
侦听器中,则会发现它确实触发了;但是,该程序仍然无法识别它不再具有要读取的行。
答案 0 :(得分:1)
似乎在nodejs v11.7中,readline接口具有异步迭代器功能,可以简单地通过for await ... of
循环进行循环;
const rl = readline.createInterface({
input: fs.createReadStream(filename);
});
for await (const line of rl) {
console.log(line)
}
How to get synchronous readline, or "simulate" it using async, in nodejs?