2

I want to run a bit of code every 20 seconds. That works fine. But I'd like setInterval to be run when first encountered, and then to start timing (instead of doing the timing first).

Obviously, I can do something like:

myFunction();
setInterval(myFunction, 20000);

But I find that a little inelegant. I'd prefer to do something like

setInterval(myFunction, 20000, { waitBeforeFirstRun: false });

Does such a setting exist for setInterval?

David Hellsing
  • 106,495
  • 44
  • 176
  • 212
chadoh
  • 4,343
  • 6
  • 39
  • 64
  • Your example is flawed, you are calling the function instead of assigning it. – epascarello Nov 07 '12 at 16:55
  • This question is a duplicate of http://stackoverflow.com/questions/6685396/execute-the-first-time-the-setinterval-without-delay .. I've also flaged it – Mihai Matei Nov 07 '12 at 16:55
  • 2
    I would go with first calling the function and then scheduling it for the sake of simplicity and maintainability. – AlexStack Nov 07 '12 at 16:58
  • @MateiMihai This is definitely a dup. What's it mean that you flagged it? Can I shut this whole thing down and just refer everyone to the other, older question? – chadoh Nov 09 '12 at 01:56
  • @AlexStack It's a good approach. My actual code was a teeny bit more complex, so it seemed easier if I wouldn't have to do that. But it was my approach until I heard back from the community on if there is a better way. It doesn't really seem like it. – chadoh Nov 09 '12 at 01:57

2 Answers2

6
(function wrap(){
    myFunction();
    setTimeout( wrap, 20000 );
})();
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • Nice idea, but how is this more elegant than `myFunction();setInterval(myFunction, 20000);`? It seems to just add another named wrapper. – David Hellsing Nov 07 '12 at 17:11
  • It's named but scoped to its body (named function expression), I.E. it won't do anything to the containing scope (global or otherwise) – Esailija Nov 07 '12 at 17:17
  • It's a neat trick. As @David indicates, it's really just a matter of personal preference and the particulars of the situation which solution to use. I wouldn't necessarily replace my original approach with this (since my code is already written at this point, I find this solution not nearly compelling enough to go change it). – chadoh Nov 09 '12 at 02:01
6

How about:

setInterval(​function foo(){
    // logic
    return foo;
}(), 20000);​
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • Very elegant! For those readers with weak JavaScript skills (me, included), a tad bit of explanation of why both the `()` and the `return` statement are necessary would be very appreciated. This is JS-nerdy enough that I'm not sure putting it in my mostly-Rubyist-written codebase would be a good idea, and will likely still keep the `myFunction();setInterval(myFunction,20000);` implementation in place (since it's already written). But your solution satisfies my curiosity and teaches me interesting things about JS. An academic success! Thanks. – chadoh Nov 09 '12 at 02:10
  • `()` will execute the function right away, and returning itself will inject the function reference into the setInterval. – David Hellsing Nov 09 '12 at 12:17