Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用async/await在Express中实现此功能_Javascript_Express_Promise - Fatal编程技术网

Javascript 如何使用async/await在Express中实现此功能

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

我正在从MongoDB服务器中的项目中读取文件名列表,然后检查本地存储中是否存在这些文件名。我试图创建一个包含所有匹配文件名的列表,这些文件名既存在于本地,也存在于数据库中,然后在一个快速响应中发送该列表

这是我想到的

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,因为它会阻塞事件循环并破坏服务器的可伸缩性。它只适用于服务器启动代码或非服务器脚本,在这些脚本中,如果阻止整个事件循环并不重要。这是否回答了您的问题?