I'm trying to make a loop fetching some info in an API, first I need this loop for to wait for the request to finish and after continue for the next array value, after the loop finish, then I need it to call that function again every 5 seconds, but only after the previous call ends.
Something like this:
let ids = [1, 2];
async function getInfoAPI(ids) {
for (const id of ids){
const apiInfo = await fetch(`https://apiurl/${id}`);
const infoJSON = await apiInfo.json();
//Do more things here
}
}
Now I need to call the function and wait for the loop to finish. After the loop is completed then wait for 5 seconds and call the getInfoFromAPI function again. I tried setInterval but if the loop, for some reason, takes more than 5 seconds to respond, the getInfoFromAPI will be called again even if it didn't finish the previous loop.
setInterval(function(){
getInfoAPI(ids);
}, 5000);
Is there any way I could do that using promises or something like that?
Thanks
CodePudding user response:
You can do something like this:
function run() {
getInfo(...).then(() => {
setTimeout(run, 5000)
});
}
run().catch(err => {
console.log(err);
});
Or, I prefer using a promise version of setTimeout()
. I the latest version of nodejs, you can use timersPromises.setTimeout()
and it returns a promise:
import { setTimeout } from 'timers/promises';
async function run() {
await getInfo(...)
await setTimeout(5000);
return run();
}
run().catch(err => {
console.log(err);
});
Or, use a while
loop with await
:
import { setTimeout } from 'timers/promises';
async function run() {
while (true) {
await getInfo(...)
await setTimeout(5000);
}
}
run().catch(err => {
console.log(err);
});
CodePudding user response:
Use recursion:
async function getInfoPeriodically() {
await getInfoAPI(ids);
setTimeout(() => {
getInfoPeriodically()
}, 5000);
}
You can add the parameters to customize this function/pass values in but this is the idea.
CodePudding user response:
You can achieve this by importing the promise based setTimeout
that ships with NodeJs 16 and using it as follows:
Import:
import { setTimeout } from "timers/promises"
Use:
while (true) {
await getInfoAPI(ids);
await setTimeout(5000);
}
CodePudding user response:
Why don't you try to use Promise.all
or Promise.allSettled
? With that you can use concurrency to fetch all the data at once, instead that one by one. In case you need to do it one by one, I suggest you to use for-await...of
.
CodePudding user response:
const delay = (ms) => new Promise(ok => setTimeout(ok, ms))
async function go(){
await getInfoAPI(ids)
await delay(5000)
await getInfoAPI(ids)
}