此答案Read a file one line at a time in node.js?显示了如何逐行读取文件。
var lineReader = require('readline').createInterface({
input: require('fs').createReadStream('file.in')
});
lineReader.on('line', function (line) {
console.log('Line from file:', line);
});
lineReader.on('close', function (line) {
console.log('Finished');
});
但是,如果我将该回调函数设为async
函数,以便我可以执行诸如验证和转换每一行并将其写入不同文件或API的操作,那么它将无法正常工作。无需等待各行完成其异步功能即可触发“关闭”事件。
是否可以使用readline
或Node.js内置的任何库逐行异步处理文件?
最简单的方法是什么?
我需要逐行执行此操作,因为文件非常大,否则将完全消耗内存。
答案 0 :(得分:0)
不要使用async function
作为回调,事件发射器不会在意返回的诺言。相反,您可以自己构建一个承诺链:
var lineReader = require('readline').createInterface({
input: require('fs').createReadStream('file.in')
});
var done = Promise.resolve();
lineReader.on('line', function (line) {
console.log('Line from file:', line);
var promise = validate(line).then(transform); // or whatever;
done = Promise.all([
done
promise
]).then(() => void 0); // needed to drop result data
// alternatively also do things that must happen sequentially
});
lineReader.on('close', function (line) {
console.log('Finished reading');
done.then(() => console.log('Finished transforming'));
});
答案 1 :(得分:0)
如this answer中所述,应该对流进行承诺化并将其转换为异步迭代器,以便有效地对promise和async..await
进行迭代。这可以通过第三方p-event
库来实现:
try {
const lineReader = require('readline').createInterface({
input: require('fs').createReadStream('file.in')
});
const asyncIterator = pEvent.iterator(lineReader, 'line', {
resolutionEvents: ['close']
});
for await (const line of asyncIterator) {
console.log('Line from file:', line);
}
} catch(e) {
console.log(e);
} finally {
console.log('Finished');
}