我正在尝试列出发送POST
请求的文件,但我无法弄清楚我在做什么有什么问题。这是我的功能:
app.post('/api/list', function(req,res){
listFiles();
res.send(files);
});
这是我的listFiles
函数和测试变量:
var files = "";
var listFiles = function(){
fs.readdir(testFolder, (err, files) => {
files.forEach(file => {
files += file;
});
console.log(files);
})
};
我可以看到带有console.log
输出的路径。但是,当我在res.send(files);
中使用POST
时,文件未显示 - 它是空的。这是我在jQuery中用来显示文件的内容:
$('li').on('click', function(){
var item = $(this).text().replace(/ /g, "-");
$.ajax({
type: 'POST',
url: '/api/list',
success: function(data){
//do something with the data via front-end framework
alert('response : ' + data);
//location.reload();
}
});
});
如果我发送res.send("test");
,我的连接就可以了。我可以将该警报消息设为"response : test"
。但是当我尝试发送变量时,它是空的。
答案 0 :(得分:2)
欢迎使用异步编程! :)
fs.readdir
异步工作,因此当您致电listFiles()
时,会立即返回并转到下一行 - res.send(files)
。在那一刻files
真的仍然是一个空字符串,所以这就是你所看到的。
fs.readdir
的回调实际上在 res.send(files)
完成后执行,因此您需要在同一res.send()
回调中执行fs.readdir
,或用Promises控制流程。
以下是一些例子:
将res
传递给listFiles,在获得所需的输出后执行res.send()
var listFiles = function (res) {
fs.readdir(..., (err, files) => {
var filesString = "";
files.forEach(...)
res.send(filesString)
})
};
app.post('/api/list', function(req,res){
listFiles(res);
});
将回调传递给listFiles,类似于第一个,但遵循相同的模式fs.readdir
使用
var listFiles = function (callback) {
fs.readdir(..., (err, files) => {
var filesString = "";
files.forEach(...)
callback(filesString)
})
};
app.post('/api/list', function(req,res){
listFiles((filesString) => res.send(filesString));
});
在承诺中包裹fs.readdir
(您也可以使用util.promisify
,查看Node docs)
var listFiles = new Promise((resolve, reject) => {
fs.readdir(..., (err, files) => {
var filesString = "";
files.forEach(...)
return resolve(filesString)
})
})
app.post('/api/list', function(req,res){
listFiles().then((filesString) => res.send(filesString))
// or, even better as Express can reply with a Promise directly
// res.send(listFiles())
});
关于NodeJS,异步编程和事件循环这是一个很好的系列,我建议你阅读它,这样你就可以了解大局:https://jsblog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810。另外,查看与 async/await 相关的内容,它会使Promise在大多数情况下更好用。