Как я могу использовать async / await, чтобы сделать эту работу в Express - PullRequest
1 голос
/ 02 марта 2020

Я читаю список имен файлов из элементов на сервере MongoDB и затем проверяю, существует ли какое-либо из этих имен файлов в локальном хранилище. Я пытаюсь создать список всех совпадающих имен файлов, которые существуют как локально, так и в базе данных, а затем отправить этот список в ответе Express.

Вот что я придумал.

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 здесь, но я не смог заставить его работать.

Ответы [ 3 ]

1 голос
/ 02 марта 2020

Вы можете использовать встроенную поддержку обещаний для библиотеки fs, а также, чтобы избежать двойного вложенности l oop, вы можете поместить список файлов в Set для более эффективной проверки каждого элемента:

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 никогда не будет совпадать с одним из имен файлов .

К вашему сведению, вам не нужна ни одна из проверок undefined. Массив files никогда не будет содержать значений undefined, поэтому, даже если item.coverUrl равен undefined, он никогда не будет соответствовать одному из файлов, поэтому он позаботится о себе таким образом, поскольку он просто никогда не будет совпадать.

0 голосов
/ 02 марта 2020

Вы можете использовать readdirSyn c (), который является синхронным способом чтения каталога.

0 голосов
/ 02 марта 2020

Библиотека «util» должна выполнить свою задачу, как показано в ответе ниже.

Использование файловой системы в node.js с asyn c / await

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...