Javascript 如何使用async/await在Express中实现此功能
我正在从MongoDB服务器中的项目中读取文件名列表,然后检查本地存储中是否存在这些文件名。我试图创建一个包含所有匹配文件名的列表,这些文件名既存在于本地,也存在于数据库中,然后在一个快速响应中发送该列表 这是我想到的Javascript 如何使用async/await在Express中实现此功能,javascript,express,promise,Javascript,Express,Promise,我正在从MongoDB服务器中的项目中读取文件名列表,然后检查本地存储中是否存在这些文件名。我试图创建一个包含所有匹配文件名的列表,这些文件名既存在于本地,也存在于数据库中,然后在一个快速响应中发送该列表 这是我想到的 app.get('/api/album', (req, res) => { let matches = []; Album.find({}).then(albums => { albums.forEach( (item, index) =>
app.get('/api/album', (req, res) => {
let matches = [];
Album.find({}).then(albums => {
albums.forEach( (item, index) => {
fs.readdir('./static/img/album-art/', (err, files) => {
files.forEach(file => {
if (file !== undefined && item.coverUrl !== undefined) {
if (file == item.coverUrl) {
matches.push(item.name);
}
}
});
});
});
});
res.json(matches);
});
但是,响应只包含一个空列表,因为fs.readdir()
是异步的。我想让它保持异步,但我正试图找到一种方法在它完成后发送响应。我对承诺不太在行,我知道我可以在这里使用async/await
,但我一直无法让它工作 “util”库应该按照下面的答案所建议的技巧进行操作
您可以使用readdirSync(),这是一种读取目录的同步方式。您可以使用
fs
库的内置promise支持,并且为了避免双重嵌套循环,您可以将文件列表放入集合
中,以便对每个项目进行更有效的检查:
const fsp = require('fs').promises;
app.get('/api/album', async (req, res) => {
let matches = [];
try {
let albums = await Album.find({});
let files = await fsp.readdir('./static/img/album-art/');
let filesSet = new Set(files);
let matches = [];
for (let item of albums) {
if (filesSet.has(item.coverUrl)) {
matches.push(item.name);
}
}
res.json(matches);
} catch(e) {
console.log(e);
res.sendStatus(500);
}
});
根据您的代码,我假设item.coverUrl
实际上只是一个基本文件名,如mysong.jpg
,而不是实际的URL,因为实际的完全限定URL永远不会匹配其中一个文件名
仅供参考,您不需要任何未定义的
检查。文件
数组永远不会包含未定义的
值,因此即使item.coverUrl
是未定义的
,它永远不会匹配其中一个文件,因此它会以这种方式自行处理,因为它永远不会匹配。在服务器请求处理程序中不建议使用同步I/O,因为它会阻塞事件循环并破坏服务器的可伸缩性。它只适用于服务器启动代码或非服务器脚本,在这些脚本中,如果阻止整个事件循环并不重要。这是否回答了您的问题?