
Subham Mitra started this conversation 8 months ago.
How to Use map() with Asynchronous Functions in JavaScript?
I’m trying to use map()
to iterate over an array and call an asynchronous function on each element, but the results are not as expected. Here’s what I tried:
const urls = ['https://api.example.com/1', 'https://api.example.com/2'];
const fetchData = async (url) => {
const response = await fetch(url);
return response.json();
}
const results = urls.map(url => fetchData(url));
console.log(results); // Promise objects instead of data
Shubham Chopra
Posted 8 months ago
When using map()
with asynchronous functions in JavaScript, you end up with an array of promises, as map()
doesn’t inherently await the results of the asynchronous functions. This is why you're seeing an array of unresolved promise objects instead of the actual data.
To handle this properly, you can use Promise.all()
to wait for all the promises to resolve.
Here’s how you can modify your code:
Updated Code Using Promise.all
:
const urls = ['https://api.example.com/1', 'https://api.example.com/2'];
const fetchData = async (url) => {
const response = await fetch(url);
return response.json();
}
// Map creates an array of promises
const promises = urls.map(url => fetchData(url));
// Wait for all promises to resolve using Promise.all
Promise.all(promises).then(results => {
console.log(results); // Now you get the data
}).catch(err => {
console.error(err); // Handle errors
});
Explanation:
-
urls.map(url => fetchData(url))
: This creates an array of promises (one for each URL). Each promise corresponds to a call tofetchData()
. -
Promise.all(promises)
:Promise.all()
waits for all promises in the array to resolve. It returns a new promise that resolves with an array of the results when all the input promises resolve. -
.then(results)
: When all promises resolve,results
contains the fetched data for each URL.
Why Use Promise.all()
:
Promise.all()
allows you to handle multiple asynchronous operations and wait until all of them are complete. It ensures that you get the results of all promises before proceeding.
Handling Errors:
- If any of the promises reject (for example, if one of the
fetch
requests fails), the wholePromise.all()
will reject. You can handle errors by adding a.catch()
block to handle any rejections. Usingasync/await
: Alternatively, you can rewrite this usingasync/await
to make the code cleaner:
const fetchDataFromUrls = async (urls) => {
const promises = urls.map(url => fetchData(url));
try {
const results = await Promise.all(promises);
console.log(results); // Data from all the URLs
} catch (err) {
console.error(err); // Handle any error
}
};
fetchDataFromUrls(urls);
Why map()
Alone Doesn't Work:
-
map()
immediately returns an array of promises without waiting for them to resolve. - To get the actual results (resolved values), you need to wait for those promises using
Promise.all()
or by awaiting each promise in a loop (if usingfor...of
withawait
inside anasync
function).
With these updates, you can ensure that the asynchronous functions in your map()
return the desired data, rather than unresolved promise objects.