我正在读取目录中的所有json文件,并以循环方式在Couchbase中对它们执行CRUD操作,以获得一些性能基准。
function readFiles(dirName,crudOps, onError){
fs.readdir(dirName,function(err,filenames){
if (err) {
onError(err);
return;
}
var circularIterator = cyclicIterator(filenames);
while(1){
fname = circularIterator.next().value;
fs.readFile(dirName + fname, function(err, content) {
console.log(fname) // NEVER REACHES HERE
if (err) {
console.log(err);
return;
}
crudOps(fname, content);
});
});
}
})
}
但是,它似乎没有执行fs.readFile
功能。我怎样才能做到这一点'循环'遍历文件名列表并使用我的crudOps
函数的文件内容?
编辑:
根据Ry的建议,我使用了承诺来阅读文件。
const readFile = util.promisify(fs.readFile);
async function getStuff(filename) {
return await readFile(filename);
}
function readFiles(dirName,onFileContent, onError){
fs.readdir(dirName,function(err,filenames){
if (err) {
onError(err);
return;
}
var iterator = circularIterator(filenames);
//filenames.forEach(function(filename) {
while(1){
fname = iterator.next().value;
//iterator.getNext(function(filename){
//
getStuff(dirName + fname).then(data => {console.log(data); onFileContent(fname, data)})
}
})
}
这是悬挂并导致我的Chrome浏览器崩溃,并且我的控制台出现以下错误:
致命错误:CALL_AND_RETRY_LAST分配失败 - JavaScript堆内存不足
有没有办法让这更好?
答案 0 :(得分:1)
您无法获得无限量的文件读取,您可以找到计算机可以处理的最大值并将程序限制为该值。
要限制活动,您可以递归调用一个函数(如果不是最大的活动进程已启动)读取文件并对其进行处理,如果已完成,则再次执行。
function readFiles(dirName, onFileContent, onError) {
fs.readdir(dirName, function (err, filenames) {
if (err) {
onError(err);
return;
}
const recur = (iterator) => {
const fname = iterator.next().value;
getStuff(dirName + fname)
.then(
data => {
console.log(data);
//if the following is an asynchronous function then
// you should wait for it to finish before calling recur
onFileContent(fname, data);
//recursively call itself
recur(iterator);
}
);
};
const iterator = circularIterator(filenames);
var i = 0;
while(i++<1000){//maximum amount of active tasks
recur(iterator);
}
})
}
工作示例:
var later = time => value =>
new Promise(
(resolve,reject)=>
setTimeout(
()=>resolve(value),
time
)
)
;
var waitTwoSeconds = later(2000);
function *myIterator(){
var i = 1;
while(i<=15){
yield i++;
}
}
function readFiles() {
const recur = (iterator) => {
const value = iterator.next().value;
if(value===undefined){
console.log("----- Done")
return;
}
waitTwoSeconds(value)
.then(
data => {
console.log("returned",data);
recur(iterator);
}
);
};
const iterator = myIterator();
var i = 0;
while(i++<5){
recur(iterator);
}
}
readFiles();