Невозможно разрешить отклонение обещания и отправить массив как ответ - PullRequest
1 голос
/ 28 апреля 2020

Я пытаюсь обработать два запроса друг в друге.

exports.get_users = (req, res) => {

  SubscriptionPlan.find()
    .then((result) => {
      if (!result) {
        return res.status(400).json({ message: "unable to process" });
      }
      let modifiedData = [];
      result.forEach(async (data) => {
        if (data.processStatus === "active") {
          await Users.findById(data.userId).then(
            (response) => {
              console.log(response)
              modifiedData.push(response);
              res.json(modifiedData)
            }
          );
        }
      });
    })
    .catch((err) => console.log(err));
};

Моя проблема возникает, если я придерживаюсь этого подхода, то получаю ошибку для отклонения обещания:

node:15036) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)

а также ответ массива modifiedData, который я получаю в почтальоне, только один объект из массива длины 3. Оператор console.log(response) возвращает 3 объекта, которые мне нужны, чтобы pu sh в новый массив.

Если я изменю свой код таким образом, чтобы разрешить отклонение,

exports.get_users = (req, res) => {

  SubscriptionPlan.find()
    .then((result) => {
      if (!result) {
        return res.status(400).json({ message: "unable to process" });
      }
      let modifiedData = [];
      result.forEach(async (data) => {
        if (data.processStatus === "active") {
          await Users.findById(data.userId).then(
            (response) => {
              console.log(response)
              modifiedData.push(response);
            }
          );
        }
      });
      res.json(modifiedData)
    })
    .catch((err) => console.log(err));
};

он вернет мне массив emtpy в качестве ответа для почтальона. Мне известно, что я застрял между асин c характером JS, но не могу решить эту проблему.

PS. Использование asyn c -wait здесь для меня бесполезно.

Любая ранняя помощь будет оценена.

1 Ответ

2 голосов
/ 28 апреля 2020

result.forEach возвращает массив обещаний. Вам нужно обещать все сразу, используя Promise.all([])

exports.get_users = (req, res) => {
  SubscriptionPlan.find().then(async (result) => {
    if (!result) {
      return res.status(400).json({ message: "unable to process" });
    }
    let modifiedData = [];
    await Promise.all(
      result.map(async(data) => {
        if (data.processStatus === "active") {
          const response = await Users.findById(data.userId);
          modifiedData.push(response);
        }
      })
    );
    return res.json(modifiedData);
  }).catch((err) => console.log(err));
};

Или можете найти сразу

exports.get_users = async (req, res) => {
  try {
    const result = await SubscriptionPlan.find({ processStatus: "active" });
    if (!result) {
      return res.status(400).json({ message: "unable to process" });
    }
    const ids = result.map(({ userId }) => userId);
    const response = await Users.find({ userId: { $in: ids } });
    return res.json(response);
  } catch (err) {
    console.log(err)
    return res.status(400).json({ message: "unable to process" });
  }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...