Асинхронный вызов API внутри цикла forEach - PullRequest
0 голосов
/ 19 октября 2018

Я столкнулся с проблемой, которую, похоже, не могу решить, полагаю, мне не хватает некоторых моментов с точки зрения асинхронного поведения.

Задача относительно проста: кошелек с деньгами в разных валютах необходимо преобразовать в единую валюту.Я хочу получить обменный курс по следующему API:

https://free.currencyconverterapi.com/api/v5/convert?q=${from}_${to}&compact=y

, где $ {from} является начальной валютой, а $ {to} целевой валютой.

Я храню различные валюты в объекте, называемом позициями, который выглядит следующим образом:

[
    {'currency': "EUR",
    "amount": 10},
    {'currency': "CNY",
    "amount": 100},
  ]

Таким образом, задача состоит в том, чтобы преобразовать 100EUR и 100CNY, например, в доллары США.

Чтобы собрать обменные курсы, я хочу перебрать отдельные позиции в следующей функции:

    collectExRates(targetCurrency) {
    let exRatesDict = {}
    this.positions.forEach( (position) => { 
      exRatesDict[position.currency] = this.parseUrl(position.currency, targetCurrency)
    });
    return exRatesDict
}

И с parseUrl, равным:

    parseUrl(from, to) {
    const exRateName = from + '_' + to;
    var rate;
    return fetchUrl(`https://free.currencyconverterapi.com/api/v5/convert?q=${from}_${to}&compact=y`, function(error, meta, body){
            rate = JSON.parse(body)[exRateName].val
            console.log("RATE", rate)
            return rate
        });
}

Я уже пробовал парутакие вещи (как создание асинхронного forEach, Promises, async await и т. д.), но я просто не могу получить ожидаемый результат, а именно вернуть словарь обменных курсов, отображающий валюту в соответствующий обменный курс.

Буду очень благодарен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

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

function fetchUrls(urlList) {
  let promises = [];
  for(idx in urlList) {
    promises.push(fetch(urlList[idx]));
  }
  return Promise.all(promises);
}

fetchUrls(your_list_of_urls)
.then(console.log)
0 голосов
/ 19 октября 2018

Проблема в том, что асинхронные методы возвращают Promise, и вам нужно дождаться их разрешения.Общий шаблон для этого следующий:

Promise.all(arr.map(v => someAsyncFunc(v))).then((resolvedValues) => {
  resolvedValues.forEach((value) => {
    // Do your stuff here
  });
});

Таким образом, в основном вы инициализируете кучу асинхронных вызовов, ожидая их разрешения с помощью Promise.all и только после этого выполняете некоторые операции с разрешенными данными.

...