I have a map function here, which is supposed to fetch data from an online source. The Problem is, that the API does only allow to fetch once per second. so I tried to do that like this:
const sleep = (ms: number) => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
};
const promises = projectData.map(async (project, index) => {
return await getAddress(asdf)
.then((nominatimData) => {
// ....do something...
})
.catch(async (e) => {
console.log("failed", e);
return await sleep(2000).then(() => {
console.log("another try... ")
return getAddress(asdf);
});
});
});
await Promise.allSettled(promises);
console.log("Project Data", projectData); //does still fire before all getAddress() are present.. :(
there are two problems I cannot figure out:
map() seems to do its job parallel (is that true?) which is kind of not what I want here - because like I said I need it to work preferably one by one every second
my sleep function does not seem to work at all. the console log is just a mess and everything at once
what would be the correct way to make this work once a second? and is the fallback (just running "getAddress) again ok like that?
thank you so much!
To answer your question:
map
does not wait for the Promise to finish to proceed to the next operation, but you can fix this using a for
loop.You could use the for loop that allows async/await operations, although, since your goal is to wait for a response from the server I would recommend a custom cursor loop instead
let cursor = 0;
const timeout = 1000;
const sleep = (ms) => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
};
const loop = async () => {
// Break if index is out of bounds
if (!projectData[cursor]) {
return console.log('Done');
}
await getAddress(projectData[cursor]).then((nominatimData) => {
// ....do something...
// Proceed to the next element in the array
cursor++;
await loop();
}).catch(async (e) => {
console.log(`Failed, retrying in ${ timeout }ms`);
await sleep(timeout);
await loop(); // Retry the loop with the same cursor index
});
};
await loop();