从统计对象

时间:2015-06-18 18:44:22

标签: javascript node.js asynchronous

我使用fs.stat获取有关文件的信息,现在我想从stats对象中获取文件名,我做了一些搜索,但没有找到任何帮助。

我现在将解释我的代码,也许有人会找到另一种解决方案,这就是我的所有代码:

function index(response, lang) {
temp.loadTpl('templates/' + lang + '/content.html', function (content) {
    fs.readdir('files/', function (err, files) {
        temp.loadTpl('templates/' + lang + '/files.html', function (data) {
            if (err) console.log(err);
            var i, fnames, len = files.length, filesNamesHTML = '';
            fnames = files;
            for (i = 0; i < len; i++) {
                fs.stat('files/' + files[i] , function (err, stats) {
                    console.log(i);
                    if (stats.isFile()) temp.write('TYPE', 'file-o');
                    else temp.write('TYPE', 'folder');
                    temp.write('FNAME', fnames[i]);
                    filesNamesHTML += temp.transTpl(data);
                });
            }
            setTimeout(function () {
                temp.write('FILES', filesNamesHTML);
                response.write(temp.transTpl(content));
            }, 100);
        });
    });
});
}

相关部分是: 我用fs.readdir来读取方向文件,然后用循环遍历结果, 对于每个文件,我都运行stat函数:

for (i = 0; i < len; i++) {
   fs.stat('files/' + files[i] , function (err, stats) {
      temp.write('FNAME', fnames[i]);
    });
}

问题在于:fnames[i],在调用回调之前,i变量已更改,并且我总是为每个文件得到相同的结果。

也许您有一个解决方案如何在stat回调函数中获取文件名。

问题发生了,因为我尝试使用异步函数...

修改 我想解决方案,谁想要......

您可以将fs.stat函数放入函数中并将此函数传递给文件名,并在stat回调函数中使用它。

1 个答案:

答案 0 :(得分:0)

您的编辑应该解决变量范围的问题。你没有很好地解释,但我知道你的意思。

你有一个for循环,它是同步的,但是你用它来启动异步函数。然后你会等到所有文件都被fs.stat编辑后再做最后一部分,假设fs.stat不会超过100毫秒。随着异步的发展,fs.stat可能不会太慢​​,所以100ms 应该足够的时间,除非你有大量的文件。但是,当你做的事情比较慢和/或花费可变的时间长度时,你需要更紧密地控制时序,以便它在完成最后一个异步位后立即执行最后一位。 / p>

有这种异步函数管理的npm模块。我将使用async模块进行回答,因为这是我所知道的模块,但使用promises的其他模块也有同样有效的方法。

我会这样做:

var async = require('async');

function index(response, lang) {
    temp.loadTpl('templates/' + lang + '/content.html', function (content) {
        fs.readdir('files/', function (err, files) {
            temp.loadTpl('templates/' + lang + '/files.html', function (data) {
                if (err) console.log(err);
                var i, fnames, len = files.length, filesNamesHTML = '';
                fnames = files;
                async.each(files, function(file, done) {
                    fs.stat('files/' + file , function (err, stats) {
                        console.log(i);
                        if (stats.isFile()) temp.write('TYPE', 'file-o');
                        else temp.write('TYPE', 'folder');
                        temp.write('FNAME', fnames[i]);
                        filesNamesHTML += temp.transTpl(data);
                        done(null);
                    });
                }, function() {
                    temp.write('FILES', filesNamesHTML);
                    response.write(temp.transTpl(content));
                });
            });
        });
    });
}

(然后做npm install async。)

还有其他一些我可以改变的东西,但这是第一次看到它时很棘手的东西所以我会克制。我只想说,如果你想编写涉及对异步函数的多次调用的javascript代码,那么值得探索async模块或类似的东西。