我正在尝试读取并解析一个大的csv文件,并且对于每一行,我必须执行一些异步计算并在完成操作后增加计数器。所以我创建了一个Promise p
并尝试链接很多.then(xxx)
,并在csv读取结束时它是最后的.then(yyy)
以输出计数。承诺中的某些可执行文件未被执行
但是这个数字没有加起来。但如果我做p = p.then(xxx)
和p = p.then(yyy)
这个数字会加起来(对于较小的csv文件),但有时我会面对内存泄漏(对于大型csv文件)。
有什么我做错了吗?
var fs = require('fs')
const csv = require('fast-csv');
var Promise = require('bluebird')
var count = 0;
var actual = 0;
let p = Promise.resolve();
const stream = fs.createReadStream(`/Users/ssmlee/Desktop/KingKong_Sims_5M.txt`);
const csvStream = csv({
delimiter: ';'
})
.on('data', (row) => {
count++
if (count % 10000 === 0) {
console.log(count)
console.log(process.memoryUsage().heapUsed)
}
p.then(() => { // instead if we do p = p.then(() => it will work correctly
return Promise.resolve().delay(5)
.then(function() {
actual++
})
});
})
.on('end',() => {
p.then(() => { // instead if we do p = p.then(() => it will work correctly
console.log(actual); // 4999977 or something like this
console.log(count); // 5000000
});
});
stream.pipe(csvStream);
你为什么认为这种方案会泄漏内存? “p = p.then(...)'没有任何问题。该结构本身不会导致内存泄漏。 – jfriend00
我在做'process.memoryUsage()。heapUsed'来检查我的内存使用情况,结果我的内存没有被垃圾回收。你可能会生成一个5m行的随机文件,看到这种情况,我想不知道为什么。 –
由于您选择实施此方法,因此您正在使用大量内存。您可以通过适当的排序来减少内存,而不是在同一时间将数十万个承诺放在飞行中。例如,您可以读取第一行,暂停CSV流,执行异步操作,然后完成释放CSV流。如果你真的想要并行执行一些操作来加速端到端的时间,但想要合理的内存使用,那么你需要一次保留一些适度的并行操作数(如10),而不是500,000。 – jfriend00