我正在寻找一些文件(每个文件大约2MB)。
起初我试过了:
for (var j = 0; j <= limit2; ++j)
fs.readFile(base + i * j + last, {encoding: "utf-8"}, function (err, data) {
cnt++;
if (cnt == limit2)
console.timeEnd("random");
});
这做得很好,但看起来阅读时间不是永远的liniar:
30 files : ~8s
300 files : ~ 12s
600 files : ~ 22s
1000 files : ~ 120s
因此,我的想法是用chucks读取那些文件。我的意思是:开始读取10个文件,等待所有文件完成,然后继续下一个10个文件,等等。
我尝试过类似的事情:
function ReadFiles() {
for (var j = 0; j <= limit2; ++j)
fs.readFile(base + i * j + last, {encoding: "utf-8"}, function (err, data) {
cnt++;
if (cnt == limit2)
// console.timeEnd("random");
});
}
for (var i = 0; i <= limit1; ++i) {
GoOn = false;
cnt = 0;
ReadFiles();
}
console.timeEnd("random");
在ReadFile函数完成之前,我应该如何使for循环暂停?
答案 0 :(得分:0)
您可以尝试使用异步模块。
对于这个用例,它有一个特殊的.queue
方法:
https://github.com/caolan/async#queue
否则你自己实现它不应该那么复杂。
答案 1 :(得分:0)
你可以做的是使用Promises,我特别喜欢 bluebird ,因为它有一些非常方便的功能。
使用bluebird,您可以向concurrency
函数提供.map()
参数,以限制一次读取的文件数。而不是等待10个文件完成,然后再分块10,它只会确保同时读取不超过10个文件:
var Promise = require('bluebird');
var fs = require('fs');
// Creates a promise returning function from a callback-based function
var readFileAsync = Promise.promisify(fs.readFile);
// Add all filenames into an array
var files = [];
for (var i = 0; i <= limit1; i++) {
for (var j = 0; i <= limit2; j++) {
files.push(base + i*j + last);
}
}
var allDonePromise = Promise.map(files, function(file) {
return readFileAsync(file, {encoding: "utf-8"});
}, { concurrency: 10 }); // Magic is here!
allDonePromise.then(function(allFileContents) {
// Here, we're all done!
});