Reputation: 557
The question is, how can I get rid of calling second fetch 300 times? Or is there another way to do that, what I`m doing? Additionally how to do ordered(don`t wanna sort) calls of first api, because they`re coming from api in chaotic asynchronous way?
for(let i=1;i<=300; i++) {
fetch(`example.api/incomes/${i}`) // should be returned 300 times
.then(response => {
if(response.ok) return response.json();
throw new Error(response.statusText);
})
.then(function handleData(data) {
return fetch('example.api') // should be returned 1 time
.then(response => {
if(response.ok) return response.json();
throw new Error(response.statusText);
})
})
.catch(function handleError(error) {
console.log("Error" +error);
});
};
Upvotes: 6
Views: 29508
Reputation: 6136
The other answers are perfectly valid, but a bit outdated. Here is a new way of doing it with async/await:
async function repeat(uri, amount) {
const result = []
for (let i = 1; i <= amount; i++) {
const response = await fetch(`${uri}/${i}`) // waits for the response
const data = await response.json()
result.push(...data)
}
return data
}
repeat('example.api/incomes', 300)
.then(handleData) // defined elsewhere or anonymous
.catch(handleError) // defined elsewhere or anonymous
}
If you don't know about this, async/await is basically a clearer way to write promises.
The
async function
declaration creates a binding of a new async function to a given name. Theawait
keyword is permitted within the function body, enabling asynchronous, promise-based behavior to be written in a cleaner style and avoiding the need to explicitly configure promise chains.
(Source)
Upvotes: 2
Reputation: 20934
Store all of your requests in an array. Then use Promise.all()
the wait for all of those requests to finish. Then when all of the requests are finished, use another Promise.all()
with a map()
inside of it to return the the JSON of each request and wait for all of those to finish.
Now your data
argument will have an array of objects available in the next then
callback.
function fetch300Times() {
let responses = [];
for(let i = 1; i <= 300; i++) {.
let response = fetch(`example.api/incomes/${i}`);
responses.push(response);
}
return Promise.all(responses);
}
const awaitJson = (response) => Promise.all(responses.map(response => {
if(response.ok) return response.json();
throw new Error(response.statusText);
}));
fetch300Times()
.then(awaitJson)
.then(data => {
fetch('example.api') // should be returned 1 time
.then(response => {
if(response.ok) return response.json();
throw new Error(response.statusText);
});
}).catch(function handleError(error) {
console.log("Error" +error);
});
Upvotes: 0
Reputation: 8125
You can solve it using Promise all.
let promises = [];
for (let i = 1; i <= 300; i++) {
promises.push(fetch(`example.api/incomes/${i}`));
}
Promise.all(promises)
.then(function handleData(data) {
return fetch("example.api") // should be returned 1 time
.then(response => {
if (response.ok) return response.json();
throw new Error(response.statusText);
});
})
.catch(function handleError(error) {
console.log("Error" + error);
});
Upvotes: 17