记录使用异步回调计算的总值

时间:2015-09-16 21:51:49

标签: javascript node.js

如果我写下面的代码,我会在每次添加文件时获得总的btye大小值。在fs.stat回调中计算后,如何仅记录总文件大小?

var fs = require('fs');

var totalBytes = 0;

function calcTotalSize(){
    //I read the files in the dir
    fs.readdir(".",function(err,files){

        files.forEach(function(filename,index) {

            fs.stat("./" + filename,function(err,stats){
                totalBytes += stats.size;
                console.log(totalBytes); // like this it logs the total updated for each items in the files array
            });    
        });
    });

    //-- log out the totalBytes --
}

calcTotalSize();

PS:我想只使用异步函数,而不是if(i == files.length)条件,如果可能的话。

4 个答案:

答案 0 :(得分:0)

你可以使用3种选择中的任何一种(我按照我的偏好顺序):

  1. 在计算所有统计信息时,使用promises获取回调。

  2. 使用fs.statSync

  3. 跟踪您已阅读的文件数量,并在达到文件总数时输出总和

  4. 由于 2 3 非常简单,我将向您展示如何使用q promise库实现 1 (那里是others类似的),应该是这样的:

    fs.readdir(".",function(err,files){
            var promises = [];
    
            files.forEach(function(filename,index) {
                var fsStatPromise = Q.nfcall(fs.stat, "./" + filename);
                promises.push(fsStatPromise);    
            });
    
            Q.all(promises).then(function(results) { 
                var total = results.reduce(function(a, b) {
                    return a.size + b.size;
                });
                console.log(total); 
            }, function(err) {
               console.log(err);
            });
        });
    

    此处使用promises vs fs.statSync的好处是,您不会失去async io的性能,这会根据您正在阅读的文件数量而有所不同。

答案 1 :(得分:0)

您遇到此探测因为readdirstat都是异步功能。解决此问题的最简单方法是使用readdirSyncstatSync

答案 2 :(得分:0)

您可以跟踪已归档的文件总数,例如:

var fs = require('fs');
var totalBytes = 0;
var filesReaded = 0;

function calcTotalSize(){
    fs.readdir(".",function(err,files){

        files.forEach(function(filename,index) {

            fs.stat("./" + filename,function(err,stats){
                totalBytes += stats.size;
                if (++filesReaded === files.length)
                  console.log(totalBytes); // log only when all the files were readed
            });    
        });
    });
}

calcTotalSize();

答案 3 :(得分:0)

要使用async fs.stat()完成总计打印,你需要一些可以控制异步流的东西,比如异步模块(别忘了安装它:'npm install async')。以下是使用async.each()的修订代码:

var fs = require('fs');
var async = require('async');

function calcTotalSize(){
    var totalBytes = 0;
    //I read the files in the dir
    fs.readdir(".",function(err,files){
        async.each(files, function(filename, eachCb) {
            fs.stat("./" + filename,function(err,stats){
                totalBytes += stats.size;
                eachCb(null);
            });
        }, function(err) {
            console.log('DONE: %d', totalBytes);
        });
    });
}

calcTotalSize();