In my JS code I needed to wait up to 3 seconds for a flag to be true. I did the following:
const waitForSomethingToBeTrue = (something) => {
const maxWaitingTime = 3 * 1000;
let promises = [];
for (let i = 100; i < maxWaitingTime; i += 100) {
promises.push(new Promise((resolve, reject) => {
setTimeout(() => {
if (something()) {
resolve();
} else {
reject(something.name + " didn't happen in " + i + "miliseconds.");
}
}, i);
}));
}
return Promise.any(promises).catch(() => {
return Promise.reject(`${something.name} didn't happen in maximum allowed
time (${maxWaitingTime} msecs).`);
});
};
As you can notice, there are a couple of problems with my approach:
how can I solve this problem without having the above issues?
I would do this with just a single promise, which either resolve
if something
is true or reject
if it gets to the time
const waitForSomethingToBeTrue = (something) => {
return new Promise( (resolve,reject) => {
let start = new Date().getTime();
const intervalId = setInterval( () => {
if(something()){
clearInterval(intervalId);
resolve();
}
else{
timer = (new Date().getTime() - start);
if( timer > 3000){
clearInterval(intervalId);
reject("took too long");
}
}
},100);
});
}
// test code below just sets a global bool to true by clicking the button
var globalBool = false;
async function testIt(){
document.querySelector("#clickme").addEventListener("click",() => globalBool = true);
try{
await waitForSomethingToBeTrue(() => globalBool);
console.log("It was true");
}
catch(error){
console.log(error);
}
}
testIt();
<button id="clickme">Click me to make something true</button>