在Node JS中使用promises
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Node JS中使用promises相关的知识,希望对你有一定的参考价值。
我正试图在这段代码上使用一个承诺:
//Listando arquivos
app.post('/readList', function(req, res) {
var cleared = false
var readList = new Promise(function(resolve, reject){
fs.readdir(req.body.path, (err, files) => {
files.forEach(file => {
console.log(file)
var fileDetail = {
name: '',
local: true,
filetype: 'fas fa-folder-open',
filepath: '',
isFile: false
}
if(!cleared){
listedFiles = []
cleared = true
}
fileDetail.name = file
fileDetail.filepath = req.body.path + file
fs.stat(req.body.path + file, function(err, stats) {
fileDetail.isFile = stats.isFile()
if(stats.isFile()) fileDetail.filetype = 'far fa-file-alt'
else fileDetail.filetype = 'fas fa-folder-open'
})
listedFiles.push(fileDetail)
})
})
})
readList.then(
console.log('vorta'),
res.end(JSON.stringify(listedFiles))
)
})
我已经推出这一行来显示列出的项目:
console.log(file)
在承诺之后将此行执行:
readList.then(
console.log('vorta'),
res.end(JSON.stringify(listedFiles))
)
我不知道哪里出错,但是控制台在文件名之前显示'vorta'。我究竟做错了什么?
正如我在之前的评论中所说,这里至少存在四个问题:
- 你没有调用
resolve(listedFiles)
来解决这个问题所以它的.then()
处理程序永远不会被调用 - 你需要将一个函数传递给
.then()
- 您没有异步操作的错误处理
- 你似乎假设
fs.stat()
是同步的,当它不是
解决此问题的最佳方法是宣传所有异步函数,然后使用promises来控制流和错误处理。这是解决所有这些问题的方法:
const util = require('util');
const fs = require('fs');
const readdirAsync = util.promisify(fs.readdir);
const statAsync = util.promisify(fs.stat);
//Listando arquivos
app.post('/readList', function(req, res) {
// add code here to sanitize req.body.path so it can only
// point to a specific sub-directory that is intended for public consumption
readdirAsync(req.body.path).then(files => {
return Promise.all(files.map(file => {
let fileDetail = {
name: file,
local: true,
filepath: req.body.path + file
};
return statAsync(fileDetail.filepath).then(stats => {
fileDetail.isFile = stats.isFile();
fileDetail.filetype = fileDetail.isFile ? 'far fa-file-alt' : 'fas fa-folder-open';
return fileDetail;
});
}));
}).then(listedFiles => {
res.json(listedFiles);
}).catch(err => {
console.log(err);
res.sendStatus(500);
});
});
仅供参考,这是一种危险的实现,因为它列出了用户传入的任何路径上的文件,因此任何局外人都可以在服务器的硬盘上看到整个文件列表。它甚至可以列出网络连接的驱动器。
您应该将qazxsw poi的范围限制为仅供公众使用的特定文件层次结构。
在这里你传递两个参数:
req.body.path
所以,你需要传递一个函数
readList.then(
//#1 In this case you're executing the log function and cause that the message is being printed.
console.log('vorta'),
res.end(JSON.stringify(listedFiles)) //# 2
)
此外,您需要在异步逻辑中调用函数readList.then(function() {
console.log('vorta');
res.end(JSON.stringify(listedFiles));
})
。
你需要将一个函数传递给resolve
。
就目前而言,您立即调用then
和log
并传递其返回值。
这是您的代码的工作副本,我做了一些您可以省略的更改,因为这些只是为您提供一个有效的代码:
end
以上是关于在Node JS中使用promises的主要内容,如果未能解决你的问题,请参考以下文章
Node.js:何时使用 Promises 与 Callbacks
如何在Node.js中对使用promises和事件发射器的函数进行单元测试?
使用 Q Promise 的 node.js 项目的代码覆盖率
如何使用 Promise 和 node.js 正确检查和记录 http 状态代码?