NodeJS

时间:2018-06-01 03:50:35

标签: javascript node.js

我正在读取目录中的所有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堆内存不足

有没有办法让这更好?

1 个答案:

答案 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();