我在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语句能够打印文件,但在返回之前只打印一个新行。
答案 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;
}
}