文件循环功能

时间:2017-06-27 16:45:40

标签: javascript node.js fs

我在node.js中创建一个循环遍历目录文件的函数。它应该将文件名添加到returnData变量,然后返回returnData。然而,它一直没有返回。我在函数中放了几个console.log语句来帮助我调试,但我无法弄清楚它为什么不起作用。

function loopMusic (directory) {
    var returnData = "";
    fs.readdir (directory, function (err, files) {

        if (err) {
            console.log (err);
        }

        files.forEach (function (file, index) {
            returnData += file;
            console.log (returnData);
        });
    });
    console.log (returnData);
    return returnData;
}

第一个console.log语句能够打印文件,但在返回之前只打印一个新行。

2 个答案:

答案 0 :(得分:2)

您可以让函数返回一个承诺:

function loopMusic (directory) {
    return new Promise((resolve, reject) => {
      fs.readdir (directory, function (err, files) {

          if (err) {
            reject(err);
            return;
          }

          files.forEach (function (file, index) {
              returnData += file;
              console.log (returnData);
          });

          resolve(returnData);
    });
}

你会以这种方式使用:

loopMusic('...')
   .then((data) => console.log(data))
   .catch((err) => ...);

答案 1 :(得分:0)

fs.readdir是异步的,这意味着当您调用它时它不会返回结果。而是将结果提供给回调,该回调在命令完成处理时调用。它“回调”你完成后提供的功能(因此得名)。

如果您想同步执行此操作,可以执行以下操作:

function loopMusic (directory) {
    var returnData = "";
    var files = fs.readdirSync(directory);
    files.forEach (function (file, index) {
        returnData += file;
        console.log (returnData);
    });
    console.log(files);
    return returnData;
}

这会返回一串文件路径,如你的问题所示。

但是,阻塞通常不是一个好主意,您应该使用异步版本。我想在这些情况下返回Promise。这是一个返回充满该字符串的promise的示例。这在技术上是没有必要的,因为可以使用回调...但是让我们假装。

function loopMusic (directory) {
    return new Promise(function(resolve, reject) {
        fs.readdir (directory, function (err, files) {
            if (err) {
                return reject(err);
            }

            let returnData = "";
            files.forEach (function (file, index) {
                returnData += file;
            });

            resolve(returnData);        
        });
    });
}

用法:

var musicPromise = loopMusic(dir);
musicPromise.then((musicStr) => console.log(musicStr)), (err) => console.log(err));

这种异步性使得它有点难以理解,因为事情没有按顺序发生,但是当使用Promises时,then()用于处理成功(或失败)时完成的事情。以后。

最后,如果您使用的是ES2017 +(最新版本的Node),则可以使用async/await模式。请记住我上面的承诺示例:

async function loopMusicAsync(directory) {
    try{
        return await loopMusic(directory); //promise returned
    }
    catch(error) {
        console.log(error); //promise rejected
        return null;
    }
}