Reputation: 51
I am currently trying to make multiple post requests to another page to run functions server side. Because these requests are part of an API call the response times will differ from call to call. So Im trying to run the calls from an array where calls will wait for a response from a function before firing the next request. Currently the calls are all being done at the same time because Im using a forEach
loop.
function update() {
ints.forEach(value => {
call(value['int']);
});
location.reload();
}
function call(value) {
$.post('PATH TO API CALL'
).success(function (resp) {
$.post('PATH TO FUNCTION'
).success(function (resp) {
// function returns true when completed
});
});
}
I would like function "update" to run through function "call" waiting for the response from function "call" that it has completed. Any help would be greatly appreciated.
Upvotes: 0
Views: 62
Reputation: 12950
The answer provided by @CertainPerformance certainly works. However, here is how I would do it.
Instead of running a for
loop and executing each individual request in a waterfall manner, I would build up an array
of promises
and then execute them at once with Promise.all
. If you do in fact need the promises to run in a waterfall manner (the response from the previous value is required for the next call), then Promise.all
probably isn't the best thing to use. In all other cases, I would use it instead.
// Some method that is actually running the request and returning the response
async function executeHttpRequest(id) {
const response = await fetch(`https://reqres.in/api/users/${id}`);
return response.json();
}
// Just a quick way to build up an array of promises.
async function callThisManyThings(num) {
const promises = Array(num).fill(null).map( async (x, i) => executeHttpRequest(i) );
const results = await Promise.all(promises);
console.log(results);
}
callThisManyThings(10);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
Upvotes: 0
Reputation: 370979
Easiest tweak would be to make both functions async
, so that you can await
each call
in a for
loop (and have call
also await
each .post
):
async function update() {
for (let i = 0; i < ints.length i++) {
// the array will be iterated through serially,
// waiting for the previous call to complete before sending out another
await call(ints[i]);
}
// the next line will only run once all iterations have finished:
location.reload();
}
async function call(value) {
const resp1 = await $.post('PATH TO API CALL' ...);
// do stuff with resp1, if needed
const resp2 = await $.post('PATH TO FUNCTION', ...)
// do stuff with resp2, if needed
}
Also make sure to .catch
in the consumer of update
to handle any errors that may be thrown.
Upvotes: 2