我正在嘗試讀取並解析一個大的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