setTimeout not working inside infinite loop

前端 未结 5 1883
花落未央
花落未央 2020-12-21 19:28
    while(true){
        window.setTimeout(function() {
            myMethod()
        }, 15000);
        }
        function myMethod() {
            alert(\"repeat\         


        
相关标签:
5条回答
  • 2020-12-21 19:33

    but once I run the code my browser hangs

    it will because you are endlessly creating setTimeout() requests by doing while(true) since it will not wait for 15 secs before doing next iteration of while

    if you want to keep alerting something every 15 sec then try

    window.setTimeout( myMethod, 15000);
    function myMethod() 
    {
        alert("repeat");
        window.setTimeout( myMethod, 15000);
    }
    
    0 讨论(0)
  • 2020-12-21 19:35

    With async/await, if you want to run an infinite loop of a function being ran every 3 seconds you can do this:

    const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
    
    (async (delay) => {
      while (true) {
          await wait(delay);
          myFunc();
      }
    }(3000); // 3 seconds
    
    0 讨论(0)
  • 2020-12-21 19:43

    setTimeout is executed asynchronously. So in your code, the infinite loop is creating an infinite setTimeouts each with a delay of 15 secs.

    0 讨论(0)
  • Javascript is single threaded (with the exception of web workers, but that is irrelavent to this example so we will ignore it). What this means is that setTimeout actually does is schedules some code to be executed some time in the future, after at least some amount of time, but only when the browser has stopped whatever else it was doing on the rendering thread at the time, which could be rendering html, or executing javascript.

    So, the code in the setTimeout can't execute until the while loop (and whatever code contains it) finishes and returns control back to the browser. But it is an infinitely loop, so control is never returned to the browser and the code in the setTimeout is never executed.

    In fact, a common idiom in javascript is to use a setTimeout with a timeout of 0 (or possibly 1) so that some code will be executed as soon as possible after the code for the current event has executed, and typically after the browser has rendered any html changes that were made by javascript.

    I don't know what your exact use case is, but you can probably do what you want either using a setInterval (which is like setTimeout but is called repeatedly at an interval), or by calling setTimeout inside the function in the setTimeout to achieve an infinite loop with recursion, but letting the browser perform other tasks in between iterations.

    0 讨论(0)
  • 2020-12-21 19:58

    The trick here, I think, would be to have the check inside the setTimeout and use clearTimeout when the condition is met. Here's an example that logs a count to the console every 1.5 seconds until 0.

    function looper(time) {
      if (time > 0) {
        console.log(time);
        var timer = setTimeout(looper, 1500, --time);
      } else {
        clearTimeout(timer);
      }
    }
    
    looper(10);
    

    You would obviously change the condition to that required by your program.

    DEMO

    0 讨论(0)
提交回复
热议问题