我无法使用fs.creadReadStream
异步处理我的csv文件:
async function processData(row) {
// perform some asynchronous function
await someAsynchronousFunction();
}
fs.createReadStream('/file')
.pipe(parse({
delimiter: ',',
columns: true
})).on('data', async (row) => {
await processData(row);
}).on('end', () => {
console.log('done processing!')
})
我希望在createReadStream
到达on('end')
之前逐个读取每条记录后执行一些异步功能。
但是,on('end')
会在我的所有数据完成处理之前被点击。有谁知道我可能做错了什么?
提前致谢!
答案 0 :(得分:2)
.on('data, ...)
不等待您的await
。请记住,async
函数会立即返回一个承诺,.on()
没有注意到这个承诺,所以它只是继续快乐地继续。
await
仅在函数内部等待,它不会阻止您的函数立即返回,因此流认为您已处理数据并不断发送更多数据并生成更多data
事件
这里有几种可能的方法,但最简单的方法可能是暂停流直到processData()
完成,然后重新启动流。
此外,processData()
是否返回与异步操作完成相关联的承诺?这也是await
能够完成工作所必需的。
readable stream doc包含在data
事件期间暂停流然后在某些异步操作完成后恢复它的示例。这是他们的榜样:
const readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes of data.`);
readable.pause();
console.log('There will be no additional data for 1 second.');
setTimeout(() => {
console.log('Now data will start flowing again.');
readable.resume();
}, 1000);
});
答案 1 :(得分:0)
我最近遇到了同样的问题。我通过使用一组承诺来修复它,并在.on("end")
被触发时等待它们全部解决。
import parse from "csv-parse";
export const parseCsv = () =>
new Promise((resolve, reject) => {
const promises = [];
fs.createReadStream('/file')
.pipe(parse({ delimiter: ',', columns: true }))
.on("data", row => promises.push(processData(row)))
.on("error", reject)
.on("end", async () => {
await Promise.all(promises);
resolve();
});
});