node.js - 异步文件读取每次读取不同数量的行,而不是停止
问题描述
我构建了一个内置于 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");
但是,我观察到这个异步包装器出现了一些不稳定和意外的行为。一方面,它无法识别文件何时结束,并且在到达最后一行时简单地挂起,从不打印“Finished”。最重要的是,当输入文件很大时,比如几千行,它总是偏离几行,并且在停止之前没有成功读取完整文件。在一个超过 2000 行的文件中,它可能会减少多达 20-40 行。如果我向.on('close'
侦听器中抛出一个打印语句,我会看到它确实触发了;但是,该程序仍然无法识别它不应再有要读取的行。
解决方案
似乎在 nodejs v11.7 中,readline 接口被赋予了异步迭代器功能,并且可以简单地通过循环进行for await ... of
循环;
const rl = readline.createInterface({
input: fs.createReadStream(filename);
});
for await (const line of rl) {
console.log(line)
}
推荐阅读
- python - 每次运行 python 脚本时更改目录
- node.js - 无效或意外令牌,我今天试图让我的机器人不和谐,但出现了这个错误
- spring - 将 Spring Boot 2.2.7 升级到 Spring Boot 2.3.0 时出错
- linux - 重命名拆分生成的文件
- javascript - onSubmit 事件处理程序在 Reactjs 表单中不起作用
- pandas - 将行值转换为列值 Pandas
- css - Material-UI Button 和 ButtonGroup 不在基线上对齐
- r - 在 R 中使用内核回归执行残差引导
- php - php字符串到十六进制with2的补码:
- c# - 谷歌视觉连接到 API 没有外部谷歌 DLL