You are reading a single comment by @allObjects and its replies. Click here to read the full conversation.
  • @CanyonCasa, indeed, there is a difference between Espruino and most JavaScript VMs: If you do a clearTimeout() or clearInterval() which have already fired or been cleared, Espruino is not happy where the others just ignore...

    A good practice for handling setTimeout()s is this pattern:

    • clear the handle in the timed function
    • check the handle before clearing the timeout and clear the handle

      var timeoutId;
      // some code...
      timeoutId = setTimeout(function(){
       timeoutId = null;
       // ...your other code....
      }, 10000);
      // ...other code...
      // code to clear the timeout ALLWAYS conditioned
      if (timeoutId) { timeoutId = clearTimeout(timeoutId); }
      

    For setInterval(), the pattern is a bit simpler:

    • check the handle before clearing the interval and clear the handle

    In both cases, the handle is a nice 'handle' to know whether a timeout is still going on or an interval is already or still going on.

    The pattern for handling timeouts become a bit tricky when the same function is used in multiple, concurrent timeouts. Even though it is easy to pass parameters in the setTimeout() and the timed function, the parameter is not ready until timeout construction function returns... Using the 'trick' to pass an object and have it updated afterwards overcomes this hurdle:

    var timeout1 = {}, timeout2 = {};
    function timedFunction(timeout) {
      timeout.id = null;
      // ...other code...
    };
    // ...more code...
    timeout1.id = setTimeout(timedFunction, 1000, timeout1);
    timeout2.id = setTimeout(timedFunction, 2000, timeout2);
    // ...some code...
    if (timeout1.id) { timeout1.id = clearTimeout(timeout1.id); }
    // ...some code again...
    if (timeout2.id) { timeout1.id = clearTimeout(timeout2.id); }
    

    Thanks for making me think through this concurrent reuse situation... so far never happened to me and the simple version worked always as desired... and does no harm when cross developing in HTML5 in Browser.

    As an allObjects's goodie, you can go all-things-are-objects-crazy and use a full fletched object to handle it nicely with class-y, object-oriented timeout instances. You can give the timeouts even names and some debug support about when set, fired, and cleared... (those fancy enhancements we leave for now with the 'dream(s)'... of which you should never ever make all come true,... running out of dreams: what would life be without dreams...)

    // setup the Timeout 'class' with 'clear()' method clearing conditionally
    function Timeout() { this.id = null; }
    Timeout.prototype.clear = function() {
      if (this.id) { this.id = clearTimeout(this.id); } };
    // some code...
    // setup timeout control object
    var timeout1 = new Timeout(), timeout2 = new Timeout();
    // some code...
    // setup timeouts
    timeout1.id = setTimeout(timedFunction,1000,timeout1);
    timeout2.id = setTimeout(timedFunction,2000,timeout2);
    // some code...
    timeout1.clear(); // conditioned only when other code needs to be included
    timeout2.clear(); // conditioned only when other code needs to be included
    

    The extra solution would be luxury Timeout class that wraps the simple language setTimeout() function... but 'boiling the ocean' could backfire: memory waste / 'leaks' (application owned) in memory-frugal MC world...

About

Avatar for allObjects @allObjects started