Reputation: 3231
I am trying to do a multiple parallel fetch requests in react-native
. But i don't get the response data as expected. What am i integrating it wrongly?
async componentDidMount() {
try {
let [res1, res2] = await Promise.all([
fetch(apiUrl1),
fetch(apiUrl2),
]);
console.warn(res1);
console.warn(res2);
}
catch(err) {
console.warn(err);
};
}
THis is the weird response i got.
{"_bodyBlob": {"_data": {"__collector": [Object], "blobId": "4", "offset": 0, "size": 661}}, "_bodyInit": {"_data": {"__collector": [Object], "blobId": "", "offset": 0, "size": 661}}, "headers": {"map": {"cache-control": "no-store, no-cache, must-revalidate", "cf-cache-status": "DYNAMIC", "cf-ray": "5", "content-type": "application/json; charset=utf-8", "date": "Thu, 09 Jan 2020 12:15:40 GMT", "expect-ct": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"", "expires": "", "pragma": "no-cache", "server": "cloudflare", "set-cookie": "ci_session=; expires=; Max-Age=7200; path=/; HttpOnly"}}, "ok": true, "status": 200, "statusText": undefined, "type": "default", "url": "apiurl"}
Upvotes: 20
Views: 23900
Reputation: 338
I'm a bit late, but it seemed like a good idea to show you how to perform multiple requests and wait for their resolution using only Promise.all
and async
/await
.
The code below also shows how to handle errors correctly for multiple HTTP requests. I mention this because due to the way fetch()
works, the catch
block of your code will not be executed when HTTP errors occur:
A
fetch()
promise only rejects when a network error is encountered (which is usually when there’s a permissions issue or similar). Afetch()
promise does not reject on HTTP errors (404, etc.). Instead, athen()
handler must check theResponse.ok
and/orResponse.status
properties. – Taken from MDN
(async () => {
try {
const urls = [
"https://api.chucknorris.io/jokes/random",
"https://api.chucknorris.io/jokes/random",
"https://api.chucknorris.io/jokes/random",
"https://api.chucknorris.io/jokes/random",
];
const requests = urls.map((url) => fetch(url));
const responses = await Promise.all(requests);
const errors = responses.filter((response) => !response.ok);
if (errors.length > 0) {
throw errors.map((response) => Error(response.statusText));
}
const json = responses.map((response) => response.json());
const data = await Promise.all(json);
data.forEach((datum) => console.log(datum));
}
catch (errors) {
errors.forEach((error) => console.error(error));
}
})();
For clarity, I also leave you an equivalent method using then()
:
(() => {
const urls = [
"https://api.chucknorris.io/jokes/random",
"https://api.chucknorris.io/jokes/random",
"https://api.chucknorris.io/jokes/random",
"https://api.chucknorris.io/jokes/random",
];
const requests = urls.map((url) => fetch(url));
Promise.all(requests)
.then((responses) => {
const errors = responses.filter((response) => !response.ok);
if (errors.length > 0) {
throw errors.map((response) => Error(response.statusText));
}
const json = responses.map((response) => response.json());
return Promise.all(json);
})
.then((data) => {
data.forEach((datum) => console.log(datum));
})
.catch((errors) => {
errors.forEach((error) => console.error(error));
});
})();
Upvotes: 23
Reputation: 1113
Use the below code if your response is coming in json
let [res1, res2] = await Promise.all([
fetch(apiUrl1).then(response => response.json()),
fetch(apiUrl2).then(response => response.json()),
]);
Upvotes: 26
Reputation: 94
The Promise.all() method returns a single Promise that fulfills when all of the promises passed as an iterable have been fulfilled or when the iterable contains no promises. It rejects with the reason of the first promise that rejects. - From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
What you just did there is assign a Promise resolve to a variable and then console.log it. Which is not what you want. Something like this should give the results you want?
async componentDidMount() {
try {
await Promise.all([
fetch(apiUrl1),
fetch(apiUrl2),
]).then([res1, res2] => {
console.warn(res1);
console.warn(res2);
});
}
catch(err) {
console.warn(err);
};
}
Upvotes: 4