为什么fs.readdir返回`undefined`?

时间:2013-05-03 23:16:20

标签: node.js

以下代码构建文件夹中文件的字典(关联数组),跳过目录和隐藏(。*)文件。系数有效,因为console.log(file_dict)在返回之前显示字典。但是,当我调用get_files函数时,return file_dict的返回值为undefined

我很确定这个问题是因为readdir是异步的。所以,我需要切换到readdirSync。但从概念上讲,我不明白为什么异步版本中的返回值未定义。

我错过了什么?

文件-explorer.js

    var fs = require('fs');

    var get_files = function() {
        fs.readdir(__dirname + '/content/', function (err, files) { 
          if (!files.length) {
            return console.log('    \033[31m No files to show\033[39m\n');
          }

          // called for each file walked in the directory
          var file_dict = {};
          var file_index = 0;

          function file(i) {
            var filename = files[i];

            fs.stat(__dirname + '/' + filename, function (err, stat) {

              if (stat.isDirectory() || filename[0] == '.'  ) {
                    // do nothing, skip these dictionaries and dot files
              } else {
                ++file_index;
                file_dict[file_index] = filename;
              };

              if (++i == files.length) {
                            console.log('right before returning');
                console.log(file_dict);
                return file_dict;
              } else {
                // continue getting files
                file(i);
              };
            });
          }
          file(0);
        });
    }


console.log ( get_files() ); // returns undefined

感谢。

1 个答案:

答案 0 :(得分:7)

异步函数不返回。他们用回程值来调用他们的回调。

考虑:

var get_files = function (cb) {
    fs.readdir(__dirname + '/content/', function (err, files) {
        if (!files.length) {
            return console.log('    \033[31m No files to show\033[39m\n');
        }

        // called for each file walked in the directory
        var file_dict = {};
        var file_index = 0;

        function file(i) {
            var filename = files[i];

            fs.stat(__dirname + '/' + filename, function (err, stat) {

                if (stat.isDirectory() || filename[0] == '.') {
                    // do nothing, skip these dictionaries and dot files
                } else {
                    ++file_index;
                    file_dict[file_index] = filename;
                };

                if (++i == files.length) {
                    console.log('right before returning');
                    console.log(file_dict);
                    return cb(file_dict);
                } else {
                    // continue getting files
                    return file(i);
                };
            });
        }
        return file(0);
    });
}


get_files(function (v) { console.log(v); });