Nodejs возвращает ответ перед ожиданием функций, содержащих обещания для разрешения - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь попасть в «категории» моей конечной точки API, чтобы получить список документов из моей коллекции категорий в firebase. Используя следующий код:

function getCategories() {
  let arr = [];
  categories
    .get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        console.log(doc.data().category);
        arr.push(doc.data().category);
        return arr;
      });
    })
    .catch(err => {
      console.log(err);
      return [1, 2, 3];
    });
}

router.route("/categories").get(async function(req, res, next) {
  let arr = await getCategories();
  res.json(arr);
});

Хотя я не получаю никаких ошибок, я получаю пустой ответ, который при отладке показывает, что arr не определено. Дело в том, что при использовании отладчика консоль регистрирует журналы внутри вызываемого forEach, и я вижу свои категории в консоли, но по какой-то причине он не ждет разрешения Firebase Promise, а маршрутизатор просто отвечает неопределенным arr переменная.

Ответы [ 4 ]

2 голосов
/ 09 февраля 2020

Ваш .then обратный вызов должен выглядеть примерно так (нет необходимости в отдельной переменной arr):

function getCategories() {
  // notice we are returning the promise
  return categories
    .get()
    .then(snapshot => {
      // notice we are returning the new array using .map()
      return snapshot.map(doc => {
        console.log(doc.data().category);
        return doc.data().category;
      });
    })
    .catch(err => {
      console.log(err);
      return [1, 2, 3];
    });
}

И, так как вы уже используете async / await, вы можете переписать это чтобы все выглядело так, чтобы ваши пользователи могли знать, когда произошла ошибка:

// notice the function is now async
async function getCategories() {
    const snapshot = await categories.get()
    // this can be a one-liner in the example above too
    return snapshot.map(doc => doc.data().category);
}

router.route("/categories").get(async function(req, res, next) {
   try {
     let arr = await getCategories();
     res.json(arr);
   } catch(ex) {
     res.status(500).json({ msg: ex.message });
   }
});
1 голос
/ 09 февраля 2020

getCategories необходимо вернуть обещание, если вы хотите использовать await для него. Прямо сейчас ничего не возвращается. Вам нужно будет вернуть созданное вами обещание:

function getCategories() {
  let arr = [];
  return categories
    .get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        console.log(doc.data().category);
        arr.push(doc.data().category);
        return arr;
      });
    })
    .catch(err => {
      console.log(err);
      return [1, 2, 3];
    });
}

Обратите внимание на ключевое слово return.

Возможно, здесь также возникла другая проблема. Вы повторяете снимок, используя forEach, и возвращаете arr из лямбда-функции, которую вы передали forEach. Это не вернет данные снимка вызывающей стороне. Вам нужно будет вернуть значение из then лямбда:

    .then(snapshot => {
      const arr = []
      snapshot.forEach(doc => {
        console.log(doc.data().category);
        arr.push(doc.data().category);
      });
      return arr;
    })
1 голос
/ 09 февраля 2020

Вы не возвращаете свое обещание и стоимость в .then. Добавьте return перед categories.get() call и верните значение затем.

0 голосов
/ 09 февраля 2020

Вы можете попробовать что-то вроде этого:

function getCategories() {
  let arr = [];
  categories
    .get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        console.log(doc.data().category);
        arr.push(doc.data().category);
        });
        console.log('arr',arr); //check the array data
        return arr;
    })
    .catch(err => {
      console.log(err);
      return [1, 2, 3];
    });
}

router.route("/categories").get(async function(req, res, next) {
  let arr = await getCategories().catch(err => {
         res.status(400).send(err);
   });
  res.json(arr);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...