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?

    1. function bar(){
    2. console.log('bar');
    3. }
    4. function foo(){
    5. console.log('foo');
    6. setTimeout(bar, 500);
    7. clearInterval();
    8. }
    9. function onInit(){
    10. console.log('onInit');
    11. setInterval(foo, 500);
    12. }
    13. onInit();

    I'm on PICO:

    1. "VERSION": "1v89.11",
    2. "BUILD_DATE": "Nov 22 2016",
  • https://www.espruino.com/Reference#l__global_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

    1. function espStatus(callback){
    2. wifi.at.cmd('AT+CIPSTATUS\r\n',1000,function(d){
    3. console.log('ESP8266 '+d);
    4. var status = d.slice(-1);//get the last character
    5. if(status == 2){//connection is good
    6. console.log('good connection');
    7. wifiTry=0;
    8. }else if(wifiTry>3){
    9. clearInterval();//clearInterval clears both intervals and timeouts!!
    10. wifiTry=0;
    11. setTimeout(startServer,500);
    12. }else{//connection is bad and we need to reconnect
    13. wifiTry++;
    14. console.log('bad connection');
    15. //need timeout to give esp8266 time to think.
    16. setTimeout(connectWifi,500);
    17. }
    18. });
    19. }
  • Here is an example that causes errors...

    1. var wifi;
    2. var wifiTry = 1;
    3. function connectWifi(){
    4. console.log("Connecting to WiFi");
    5. wifi.connect("access","password", function(err) {
    6. if (err) {
    7. throw err;
    8. }
    9. console.log("Connected!");
    10. wifi.getIP(function(e, ip) {
    11. LED2.set();
    12. console.log(ip);
    13. });
    14. });
    15. }
    16. //checks the ESP8266 connection status
    17. function espStatus(callback){
    18. wifi.at.cmd('AT+CIPSTATUS\r\n',1000,function(d){
    19. console.log('ESP8266 '+d);
    20. var status = d.slice(-1);//get the last character
    21. if(status == 2){//connection is good
    22. console.log('good connection');
    23. wifiTry=0;
    24. }else if(wifiTry>1){
    25. clearInterval();//clearInterval is causing issues here
    26. wifiTry=0;
    27. console.log('end');
    28. }else{//connection is bad and we need to reconnect
    29. wifiTry++;
    30. console.log('bad connection');
    31. //need timeout to give esp8266 time to think.
    32. setTimeout(connectWifi,500);
    33. }
    34. });
    35. }
    36. function onInit() {
    37. clearInterval();
    38. E.enableWatchdog(10, true); //should restart the pico if it freezes
    39. // initialise the ESP8266, after a delay
    40. setTimeout(function() {
    41. digitalWrite(B9,1); // enable on Pico Shim V2
    42. Serial2.setup(115200, { rx: A3, tx : A2 });
    43. wifi = require("ESP8266WiFi_0v25").connect(Serial2, function(err){
    44. if(err){
    45. throw err;
    46. }
    47. connectWifi();
    48. setInterval(espStatus, 30000);
    49. });
    50. }, 2000);
    51. }

    And this is the error:

    1. Uncaught Error: Unknown Timeout
    2. at line 1 col 52
    3. ...))?(d=p,b=f):clearTimeout(e);void 0===d&&0<g.length&&(a=g.sh...
    4. ^
    5. in function "d" called from line 1 col 324
    6. ...c&&(e[c](k),n=!0);n||d&&d(k)}a=a.substr(f+1);"\n"==a[0]&&(a=...
    7. ^
    8. 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

    1. clearTimeout(timer);
    1. // 红外移动传感 FIR800 5v
    2. // http://www.espruino.com/Pyroelectric
    3. // Relay: low level trigger
    4. function run() {
    5. var timer;
    6. var pyreolectric = A0;
    7. var relay = A1;
    8. var delay = 20000; // 20 sec
    9. setWatch(function () {
    10. console.log("Movement detected");
    11. LED2.write(1);
    12. digitalWrite(relay, 0);// trigger relay: ON
    13. if (timer !== undefined) {
    14. clearTimeout(timer); // debounce
    15. }
    16. timer = setTimeout(function () {// trigger relay: OFF
    17. LED2.write(0);
    18. digitalWrite(relay, 1);
    19. }, delay);
    20. }, pyreolectric, { repeat: true, edge: "rising" });
    21. }
    22. 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:

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

    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
    • $ Donate
About

clearInterval is killing setTimeout

Posted by Avatar for Cale @Cale

Actions