Multiple return values from multiple promises

Multiple return values from multiple promises

Let’s assume we want to retrieve some data from an API and show it together with the original data. For instance, I’ll use the DuckDuckGo API to find capital names for countries.

One country

If I search for a country, let’s say Peru, many browsers will return brief information about that country, including the capital city. I used DuckDuckGo because it provides that information and has fair API usage.

Let’s start with analyzing the result in a browser by opening the page:

https://api.duckduckgo.com/?q=$Peru&skip_disambig=1&format=json&pretty=1

So we’re searching for Peru, discard the disambiguation information (skip_disambig=1), return the result as a JSON (format=json) and format the result to be readable (pretty=1). The last part won’t be necessary to use in the code (parsing doesn’t need pretty print ;)).

I found that the information about the capital is stored in Infobox => content => (something with label Capital). Therefore in order to get the capital of one country, I can write:

JS

Result:

Peru - Lima

It works well. Notice the problem here: in the final command I need access to both country and capital. (I bet the country can be retrieved from the result as well, but it won’t always be the case).

Multiple countries

Now let’s get results for several countries by putting that routine in a loop:

JS

Result:

Argentina - Buenos Aires
Peru - Lima
Ghana - Accra
New Zealand - Wellington

Well, not so cool now. Although we have all the results, they are put in random order. Sometimes it’s fine. But sometimes not. What then? Use asynchronous programming!

Sorted with single Promise

One option is using single Promises. Take a look at this example:

JS

Since fetch returns a Promise, we can use the async/await keywords to wait for it and then process it further synchronously.

The strange (async () => { ... })() syntax is an IIFE – Immediately Invoked Function Expression. It’s useful if you don’t have an async function to put the code in.

Another way of doing the same is by removing the chaining:

JS

Result:

Peru - Lima
Argentina - Buenos Aires
New Zealand - Wellington
Ghana - Accra

The problem with these both approaches is that the API calls are now executed one at time. It works, but it’s slow. Because after every fetch, we return for the result before proceeding.

Sorted with parallel calls

The solution is first calling all APIs, then processing the results.

JS

Result:

??? - Lima
??? - Buenos Aires
??? - Wellington
??? - Accra

Now it works much faster, but… how to get the country name? The most reliable way is to attach it to the promise!

JS

Result:

Peru - Lima
Argentina - Buenos Aires
New Zealand - Wellington
Ghana - Accra

It is possible to return an array instead of an object:

JS

but it’s less clear what is inside c[0] and c[1].

Leave a Reply

avatar
  Subscribe  
Notify of