【问题标题】:File Loop Function文件循环功能
【发布时间】:2017-06-27 16:45:39
【问题描述】:

我正在 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 语句能够打印文件,但在 return 之前的语句只打印一个新行。

【问题讨论】:

标签: javascript node.js fs


【解决方案1】:

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

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) => ...);

【讨论】:

  • 这是真的!我会修好它。谢谢!
【解决方案2】:

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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2012-08-18
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多