To run multiple tasks simultaneously, you can utilize the map
method on an array and integrate fetch
within it. Tracking when all tasks have completed is achievable by employing Promise.all
to monitor the overall outcome:
await Promise.all(
data.entries().map(async (index, item) => {
const res = await fetch(
`https://dnscheck.io/api/query/?id=${item.id}&type=${query.type}&hostname=${query.host}`
);
// Verify the response using `res.ok` at this point
const result = await res.json();
renderResult(result, item, index);
)
);
It is important to note that Promise.all
will immediately reject its promise if any of the input promises encounters a rejection. If you need to differentiate between successes and failures, consider using allSettled
instead:
const results = await Promise.allSettled(
data.entries().map(async (index, item) => {
const res = await fetch(
`https://dnscheck.io/api/query/?id=${item.id}&type=${query.type}&hostname=${query.host}`
);
// Check the response status with `res.ok` here
const result = await res.json();
renderResult(result, item, index);
)
);
// Utilize `results`, which is an array of objects representing success or failure
// {status: "fulfilled", value: <the fulfillment value>}
// or
// {status: "rejected", reason: <the rejection reason>}
In reference to my observation "Verify the response using res.ok
at this point": This cautionary advice pertains to an inherent issue in the fetch
API where it does not reject promises for HTTP errors like a 404
. Instead, it treats such cases as fulfilled promises. You can find more insights on this topic in my article found here. A recommended approach is to implement wrapper functions for handling these situations, as shown below:
function fetchJSON(...args) {
return fetch(...args)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`); // Or a more specific error type
}
return response.json();
});
}