Обещание в рамках обещания для вызова Express Router - React - Redux - PullRequest
0 голосов
/ 27 марта 2019

У меня проблемы с объединением в цепочку моих вызовов API, чтобы один не заканчивался раньше другого.

Я хотел бы запросить из первого API-интерфейса все учетные записи, указанные для пользователя, затем я хотел бы взять возвращенный массив учетных записей и запросить остатки их счетов из другой базы данных.Наконец, добавьте остатки к их объекту учетной записи и res.json (массив учетных записей).

Проблема, с которой я столкнулся, заключается в том, что запрос, который находит учетные записи, не ожидает запроса, который добавляет остатки для завершения, и все остатки отправляются в мое состояние как неопределенное.Я выяснил это с помощью console.log () во всех двух запросах (не показано ниже).

Я относительно новичок в обещаниях от вызовов API, поэтому я не уверен, что это лучший способ сделатьЭто.Мне не повезло с нотацией .all для обещаний, которые у меня есть ниже, я не уверен, что это лучший способ сделать это, поскольку после первого вызова API может быть возвращено несколько учетных записей.

Вот первый вызов API, который запрашивает учетные записи.

router.get(
  "/accounts",
  passport.authenticate("jwt", { session: false }),
  (req, res) => {
    Account.find({ userId: req.user.id })
      .then(accounts => {
        return accounts.map((account) => addBalanceToAccount(account));
      }).all( (ret) => {
          // NOT SURE WHAT TO DO HERE
          ret.then((value) => console.log(value));
          res.json(ret)
      })
      .catch(err => console.log(err));
  }
);

Второй вызов API находится в функции addBalanceToAccount (account).В основном я использую ACCESS_TOKEN для запроса базы данных.ACCESS_TOKEN может быть привязан к нескольким учетным записям, поэтому я фильтрую их только для учетной записи, которая соответствует идентификатору учетной записи.

Иногда Банк возвращает объект ошибки вместо баланса, поэтому в этом случае будет получено значение === undefined.

Моя идея с этой функцией состоит в том, чтобы вернуть обещание, то есть клиент возврата, затем использовать раздражающую функцию в обещании, чтобы вернуть новый объект счета с добавленным балансом.

function addBalanceToAccount(account){
  ACCESS_TOKEN = account.accessToken;
  let value;
  let accountFound;

  return client
    .getBalance(ACCESS_TOKEN)
    .then(response => {
        accountFound = response.accounts.filter((a) => a.account_id === account.accountId);
        value = accountFound.length > 0 ? accountFound[0].balances.current : -2;
        return value === undefined ? {...account, balance: -1} : {...account, balance: value}
    })
    .catch(err => {console.log("ERROR"); return {...account, balance: -3};});
}

Этомой ход мыслей ...

return accounts.map () должен возвращать массив Promises, поэтому я использую .all ().Затем в .all () я смогу подождать, пока все учетные записи запросят свои балансы.В конце res.json () должен вернуть массив объектов аккаунта, в которых есть ключ {balance: value}

1 Ответ

0 голосов
/ 01 апреля 2019

Нашел способ заставить его работать.Просто пришлось настроить мой вызов .all ():)

router.get(
  "/accounts",
  passport.authenticate("jwt", { session: false }),
  (req, res) => {
    Account.find({ userId: req.user.id })
      .then(accounts => {
        Promise.all(accounts.map((account) => addBalanceToAccount(account)))
          .then((accountList) => res.json(accountList))
      })
      .catch(err => console.log(err));
  }
);
...