clearInterval is killing setTimeout

Posted on
  • Shouldn't the following code output (from console.log()) onInit, foo, bar ?? Instead on onInit, foo ??
    It seems that clearInterval is killing the setTimeout? That's not normal is it?

    function bar(){
      console.log('bar');
    }
    
    function foo(){
      console.log('foo');
      setTimeout(bar, 500);
      clearInterval();
    }
    
    function onInit(){
      console.log('onInit');
      setInterval(foo, 500);
    }
    onInit();
    

    I'm on PICO:

    "VERSION": "1v89.11",
      "BUILD_DATE": "Nov 22 2016",
    
  • https://www.espruino.com/Reference#l__gl­obal_clearInterval

    If no argument is supplied, all timers and intervals are stopped

    So it is doing what is says on the box...

  • ugh... I just seen that. ok

  • under else if statement: Still clearing the setTimeout even though it is run after clearInterval

    function espStatus(callback){
      wifi.at.cmd('AT+CIPSTATUS\r\n',1000,func­tion(d){
        console.log('ESP8266 '+d);
        var status = d.slice(-1);//get the last character
        if(status == 2){//connection is good
          console.log('good connection');
          wifiTry=0;
        }else if(wifiTry>3){
          clearInterval();//clearInterval clears both intervals and timeouts!!
          wifiTry=0;
          setTimeout(startServer,500);
        }else{//connection is bad and we need to reconnect
          wifiTry++;
          console.log('bad connection');
          //need timeout to give esp8266 time to think.
          setTimeout(connectWifi,500);
        }
      });
    }
    
  • Here is an example that causes errors...

    var wifi;
    var wifiTry = 1;
    function connectWifi(){
      console.log("Connecting to WiFi");
      wifi.connect("access","password", function(err) {
        if (err) {
          throw err;
        }
        console.log("Connected!");
        wifi.getIP(function(e, ip) {
          LED2.set();
          console.log(ip);
        });
      });
    }
    //checks the ESP8266 connection status
    function espStatus(callback){
      wifi.at.cmd('AT+CIPSTATUS\r\n',1000,func­tion(d){
        console.log('ESP8266 '+d);
        var status = d.slice(-1);//get the last character
        if(status == 2){//connection is good
          console.log('good connection');
          wifiTry=0;
        }else if(wifiTry>1){
          clearInterval();//clearInterval is causing issues here
          wifiTry=0;
          console.log('end');
        }else{//connection is bad and we need to reconnect
          wifiTry++;
          console.log('bad connection');
          //need timeout to give esp8266 time to think.
          setTimeout(connectWifi,500);
        }
      });
    }
    
    function onInit() {
      clearInterval();
      E.enableWatchdog(10, true); //should restart the pico if it freezes
      // initialise the ESP8266, after a delay
      setTimeout(function() {
        digitalWrite(B9,1); // enable on Pico Shim V2
        Serial2.setup(115200, { rx: A3, tx : A2 });
        wifi = require("ESP8266WiFi_0v25").connect(Seri­al2, function(err){
          if(err){
            throw err;
          }
          connectWifi();
          setInterval(espStatus, 30000);
        });
      }, 2000);
    }
    

    And this is the error:

    Uncaught Error: Unknown Timeout
     at line 1 col 52
    ...))?(d=p,b=f):clearTimeout(e);void 0===d&&0<g.length&&(a=g.sh...
                                  ^
    in function "d" called from line 1 col 324
    ...c&&(e[c](k),n=!0);n||d&&d(k)}a=a.subs­tr(f+1);"\n"==a[0]&&(a=...
                                  ^
    in function called from system
    
  • You shouldn't really use just clearInterval/clearTimeout without an argument unless it's on initialisation when you do really want to clear everything. Just remember the timeout value returned by setInterval/etc and use that.

    What you're doing is you're clearing all timeouts - including the one that was set up inside the ESP8266WiFi module - and then the wifi module is complaining, not your code.

  • Ok got it. Thank you

  • You shouldn't really use just clearInterval/clearTimeout...

    @Gordon, I guess you wanted to say ...without arguments.

    And even on initialization it could interfere with something that should survive an onInit(), such as permanently saved code, for - for example - support of update over the air.

    Therefore, best practices are:

    • 'do not' set intervals or timeouts on upload time
    • 'always' have an onInit() {... (or E.on("init", function(){...) that intentionally starts your code... including all timeouts and intervals
    • when saving code, save it 'always before running it' (before invoking init())


    Code in level 0 (or root level) is executed by Espruino at upload time (see Simple explanation how to save code that Espruino runs on start?).

    Even if the intervals or timeouts are embedded a function but that function is - directly or indirectly - called in level 0 (after its definition), those intervals and timeouts get set on upload. Unpredictable behavior and weird side effects are usually the result when saving code that has already began running.

  • Just added - thanks :)

  • I got an error :

    in function called from system
    Uncaught Error: Unknown Timeout
    at line 17 col 31

            clearTimeout(timer);
    
    // 红外移动传感 FIR800 5v
    // http://www.espruino.com/Pyroelectric
    // Relay: low level trigger
    
    function run() {
        var timer;
        var pyreolectric = A0;
        var relay = A1;
        var delay = 20000; // 20 sec
    
        setWatch(function () {
            console.log("Movement detected");
            LED2.write(1);
            digitalWrite(relay, 0);// trigger relay: ON
    
            if (timer !== undefined) {
                clearTimeout(timer); // debounce
            }
    
            timer = setTimeout(function () {// trigger relay: OFF
                LED2.write(0);
                digitalWrite(relay, 1);
            }, delay);
        }, pyreolectric, { repeat: true, edge: "rising" });
    }
    E.on('init', run);
    
    

    Does the code have some mistakes ? Help, thx!

  • The only problem you have is that when the setTimeout fires, it doesn't automatically set timer to undefined.

    If you did:

    timer = setTimeout(function () {// trigger relay: OFF
       timer = undefined;
       ....
    

    it would probably fix it?

  • I use timer to flag if action be done.
    I set timer = undefined after clear it.

    Resolved.
    thx!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

clearInterval is killing setTimeout

Posted by Avatar for Cale @Cale

Actions