Sometimes you’re in JS and you want to perform some task once something else returns (as is reasonable in an asynchronous world), but if you just fire off a bunch of intervals, you’ll eventually choke the browser. My solution is to add geometric timer falloff and a maximum timeout. this way the longer the task takes the less work we do as we wait, and at some point (in this example ~16 seconds) it gives up. This strategy has been working well for me.
if(!Function.actionTimeout) Function.actionTimeout = 16384; | |
if(!Function.whenTrue){ | |
Function.implement({ | |
whenTrue : function(actionFunction, args, delayFunction, timeoutFunction, timeout, counter){ | |
if(!timeout) timeout = Function.actionTimeout; | |
if(!counter) counter = 0; | |
if(!timeoutFunction) timeoutFunction = function(event){ | |
throw('Condition not met after '+event.time+'ms'); | |
}; | |
var result = this(); | |
if(!result){ | |
var delayTime = Math.pow(2, counter); // geometric falloff | |
if(delayTime >= timeout){ | |
timeoutFunction({ | |
count : counter, | |
time : delayTime | |
}); | |
return; | |
} | |
counter++; | |
this.whenTrue.delay(delayTime, this, [actionFunction, args, delayFunction, timeoutFunction, timeout, counter]); | |
if(delayFunction) delayFunction({ | |
count : counter, | |
time : delayTime | |
}); | |
}else{ | |
actionFunction.apply(this, args); | |
} | |
} | |
}); | |
} |
Then call it like:
(function(){ | |
//code here | |
}).whenTrue(function(arg1){ | |
//code here | |
}, [val1]); |
or
myFunction.whenTrue(function(arg1){ | |
//code here | |
}, [val1]); |
Enjoy,
-abbey