承诺性能问题。阅读文件太慢

时间:2017-08-01 18:03:29

标签: node.js io promise bluebird

我使用promises读取硬盘中的10000多个文件,并在确切的位置找到一个数字。我使用glob来返回文件名,并且对于发现的每个文件,我运行方法readFile(readFile返回为promisse)。处理完所有文件后,我可以继续工作。

function readFilesGlob(globPath,options,progressCallback){
    return new Promise(function (fulfill, reject){

      glob(globPath, options, function (err, files) {
        var readPromisses=[];
        for(var id in files){
          readPromisses.push(readFile(files[id]));
        }

        Promise.all(readPromisses).then(
          function(filesContents){
            fulfill(filesContents)
          }
        ); 

      });
    });
  }

所有承诺仅在一切完成后才完成,使其无法显示处理进度

function readFilesGlob(globPath,options,progressCallback){
    return new Promise(function (fulfill, reject){

      glob(globPath, options, function (err, files) {
        var readPromisses=[];
        for(var id in files){
          readFile(files[id]).then(function(data){
            //everything shows at the same time, like i was using the Promise.all
            console.log(data)
          })
        }
        //just testing the speed of the return in the console.log above
        fulfill();

      });
    });

问题是。它太慢了,我几分钟后才回来(或者当我内存不足时)

我正在使用承诺错误。有人能给我一个更具性能的例子来阅读带有承诺的文件列表吗?

3 个答案:

答案 0 :(得分:1)

我认为在你的for循环中你需要这样的东西

readPromisses.push(
   new Promise( function(y,n) { readFile(files[id]); y();} )
)

readFile开始执行异步时,将调用Promise。 这只是一个建议,我还没有对此进行过测试,因此您可能需要稍微调整一下。

这是一个骨架,也许会有所帮助

var firstCall  = new Promise((y, n) => setTimeout( () =>  y(Math.random()), 500 ));

var secondCall = (arg) => {
    return new Promise((y, n) => setTimeout( () =>  y(Math.random() + ' ' +  arg), 200 ));
}

var rejectCall = () => new Promise((y, n) => setTimeout( () =>  n(true), 400 ));

Promise.all([
    firstCall,
    secondCall('withArg'),
]).then( (data) => {
    console.log( 'ALL: First Call result:',  data[0]);
    console.log( 'ALL: Second Call result:', data[1]);
}).catch( (err) => {
    console.log( 'Promise.all caught reject or error:', err);
});

答案 1 :(得分:1)

这似乎是async包的绝佳解决方案!

结帐each功能:https://caolan.github.io/async/docs.html#each

示例:

// assuming openFiles is an array of file names
async.each(openFiles, function(file, callback) {

    // Perform operation on file here.
    console.log('Processing file ' + file);

    if( file.length > 32 ) {
      console.log('This file name is too long');
      callback('File name too long');
    } else {
      // Do work to process file here
      console.log('File processed');
      callback();
    }
}, function(err) {
    // if any of the file processing produced an error, err would equal that error
    if( err ) {
      // One of the iterations produced an error.
      // All processing will now stop.
      console.log('A file failed to process');
    } else {
      console.log('All files have been processed successfully');
    }
});

我几乎在所有项目中都使用异步软件包,速度快且功能强大且<3

替代方案:使用队列系统

设置一个队列系统,我使用的是kue,这样你也可以检查你的任务进度&#39;

答案 2 :(得分:1)

如果I / O出现问题,您可以拆分您的文件&#39;数组成块,并链接这些块。

chunks.reduce((result, chunk) => {
   return Promise.all(chunk.map(file=> promiseRead(file))
   .then(results => dealWithChunkResults(results)
}, Promise.resolve())