3

What is the best and DRYest way to write code that can be executed either when some time has passed (say, 5 seconds) or some condition is met (e.g. bool = true) - whichever comes first. The five seconds start counting from when the script first ran, and the boolean is a global that is changed by another function. I don't think you can combine the time out and the bool-check in one statement, but another good way is also good.

Pseudo code:

if (bool = true OR timePassed = 5000):
    runCode()
Bram Vanroy
  • 24,991
  • 21
  • 120
  • 214

5 Answers5

3

None of the answers actually provide a full answer to the question, namely the whichever comes first is not implemented -- or the final code is run twice.

You need a timer, and a condition (as other answers suggested but failed to combine in one whole).

var done = false;
var thisTimeout = setTimeout(function() {
    myFunction();
}, 1000);

if ((someCondition) && !done) {
    myFunction();
}
function myFunction() {
    clearTimeout(thisTimeout);
    done = true;
    // Do stuff
}
Bram Vanroy
  • 24,991
  • 21
  • 120
  • 214
2

You can set a timeout and cancel it if the function is called before the time limit is reached.

var timeout = setTimeout(function() {
    runCode();
}, 5000);

function runCode() {
    clearTimeout(timeout);
    ...
}

Edit: Now that I think of it, a better way to set the timeout in this instance would be

var timeout = setTimeout(runCode, 5000);
DonovanM
  • 1,164
  • 1
  • 12
  • 16
  • And what if the timer runs out *before the boolean* is set? How do you cancel it the other way around? – Bram Vanroy May 02 '16 at 07:48
  • @BramVanroy You will [need a flag](http://stackoverflow.com/a/36971492/2788872) indicating whether the condition has already been met previously. – John Weisz May 02 '16 at 10:17
0

The following code uses two global variables, condition and seconds. The timer runs every second and increases seconds by 1 if condition is not true or seconds are not more than 4.

condition = false // global
seconds = 0 // global

var timer = setInterval(function() {
if (condition || seconds > 4) {
    clearInterval(timer)
}
seconds+=1;
}, 1000);
Joe Beans
  • 304
  • 2
  • 4
0
window.onload = function(){
    var timer = setTimeout(RunCode, 5000);
    function RunCode(){
        //do something
        //RunCode() already done and we don't want to run it second time
        element.onevent = function(){};
    }
    //pseudo code
    element.onevent = function(){
        clearTimeout(timer);
        RunCode();
    }
    //possibly more event handlers with similar logic
}
Alex Kudryashev
  • 8,750
  • 3
  • 26
  • 33
-1

Isn't setTimeout what you are looking for?

setTimeout(function() {
    if (mycondition) {
        //do work
    }
}, 1000);

Will wait 1000ms and do the statement. If your boolean condition is an event based thing then you could listen for it. What causes the boolean to become true? It sounds like the timeout is irrelevant and so we just need to check the condition probably every 100ms:

setInterval(function() {
    if (mycondition) {
        //do work
    }
}, 100);

Does that help you?

So the full solution:

var mytimeout, myinterval;
mytimeout = setTimeout(function() {
        //do work
      clearInterval(myinterval);
}, 5000);
myinterval = setInterval(function() {
      if (condition) {
          clearTimeout(mytimeout);
          //dowork
      }
}, 100);
PeterS
  • 2,557
  • 22
  • 33
  • 1
    No. I want to run some code EITHER when a condition is met OR when a timer runs out. Whichever comes first. – Bram Vanroy May 01 '16 at 20:13
  • Then use both, one with a small interval just checking the condition and the timeout that runs the code if complete. If either execute cancel the other one. – PeterS May 01 '16 at 20:17