简体   繁体   中英

async API call inside forEach loop

I ran into a problem that I cannot seem to solve, I'm guessing I'm missing some points in terms of async behaviour.

The task is relatively simple: A wallet with money in different currencies needs to be transformed into a single currency. I want to get the exchange rate from following API:

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

With ${from} being the starting currency and ${to} the target currency.

I store the different currencies in an object called positions, that looks like this:

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

So the task would be to transform the 100EUR and 100CNY in for example USD.

To gather the exchange rates, I want to iterate through the single positions in following function:

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

And with parseUrl being:

    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
        });
}

I already tried a couple of things (like creating an async forEach, Promises, async await, etc.), but I just can not get the intended result, which is to return the exchange rates dictionary mapping a currency to it's respective exchange rate.

I will be very thankful for any help.

The problem is that async methods returns Promise and you need to wait them to resolve. The common pattern to do this is next:

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

So basically you are initializing bunch of async calls, waiting for them to resolve with Promise.all and only after that preform some operations on resolved data.

You should try something like this:

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM