The difference and conversion between setTimeout() and setInterval()

【Foreword】

      Following the previous article, here is the difference and conversion between setTimeout() and setInterval()

      setTimeout() and setInterval() are often used to handle delayed and timed tasks.

 

【the difference】

      ①setTimeout() method is used to call a function or calculation expression after a specified number of milliseconds;

      ②setInterval() can call the function or expression cyclically every specified number of milliseconds until clearInterval clears it

      3 From the definition, we can see that the two functions are very similar, except that the former is executed once, while the latter can be executed multiple times. The parameters of the two functions are also the same. The first parameter is the code or handle to be executed, and the second parameter is the code or handle to be executed. is the delay in milliseconds.

     Very simple definition and easy to use, but sometimes our code is not called at the exact time we imagined, which is very confusing

 

【Details】

(1) Simple example

      Look at a simple example, a simple page writes Delayed alert two seconds after loading!

setTimeout('document.write("Delayed alert!");', 2000);

      It seems reasonable, let's look at another example of the setInterVal() method

var num = 0;
        var i = setInterval(function() {
            num++;
            var date = new Date();
            document.write(date.getMinutes() + ':' + date.getSeconds() + ':' +
                           date.getMilliseconds() + '<br>');
            if (num > 10)
                clearInterval(i);
        }, 1000);

   The page records the current time (minutes:seconds:milliseconds) every 1 second, and clears it after ten times of recording, and no longer records. Considering that the code execution time may not record the execution time, but the time interval should be the same, see the result

43:38:116
43:39:130
43:40:144
43:41:158
43:42:172
43:43:186
43:44:200
43:45:214
43:46:228
43:47:242
43:48:256

 

(2) Analysis of the reasons

      The time interval is almost 1000ms but not precise, why is that? The reason is that we have a misunderstanding of JavaScript timers. JavaScript actually runs in a single-threaded environment, which means that the timer only schedules the execution of the code at a certain time in the future, and the specific execution timing cannot be guaranteed. Because there may be other code controlling the JavaScript process at different times during the life cycle of the page. After the page is downloaded, the code runs, event handlers, and Ajax callback functions all use the same thread. In fact, the browser is responsible for sorting and assigning the priority of a certain program to run at a certain point in time.

      Let's zoom in on the effect and add a time-consuming task

function test() {
            for (var i = 0; i < 500000; i++) {
                var div = document.createElement('div');
                div.setAttribute('id', 'testDiv');
                document.body.appendChild(div);
                document.body.removeChild(div);
            }
        }
        setInterval(test, 10);
        var num = 0;
        var i = setInterval(function() {
            num++;
            var date = new Date();
            document.write(date.getMinutes() + ':' + date.getSeconds() + ':' +
                           date.getMilliseconds() + '<br>');
            if (num > 10)
                clearInterval(i);
        }, 1000);

   We added another timed task to see the results

47:9:222
47:12:482
47:16:8
47:19:143
47:22:631
47:25:888
47:28:712
47:32:381
47:34:146
47:35:565
47:37:406

   This time the effect is obvious, the gap is even more than 3 seconds, and the gap is very inconsistent.

   We can think of JavaScript as running on a timeline. When the page loads, the method and variable declarations and data processing to be used later in the page life cycle are executed first, after which the JavaScript process will wait for more code to execute. When the process is idle, the next piece of code will be fired

   In addition to the main JavaScript process, you also need a queue of code to execute the next time the process is idle. Over the life of the page, the code will be added to the queue in the order of execution, for example when a button is pressed his event handler will be added to the queue and executed at the next possible time. When an Ajax response is received, the code for the callback function is added to the queue. No code in JavaScript is executed immediately, but as soon as the process becomes idle. The way timers work with queues is that code is inserted when a certain amount of time has elapsed, which doesn't mean it will execute right away, only that it executes as soon as possible.

   After knowing this, we can understand that if we want precise time control, we cannot rely on JavaScript's setTimeout function.

 

(3) Repeating timer

      The timer created by setInterval() can make the code execute in a loop. When the specified effect is reached, the interval can be cleared, as shown in the following example

var my_interval = setInterval(function () {
            if (condition) {
                //..........
            } else {
                clearInterval(my_interval);
            }
        }, 100);

       But the problem with this method is that the code of the timer may not be executed before the code is added to the queue again. As a result, the judgment condition in the loop is inaccurate, and the code is executed several times without pause. JavaScript has solved this problem, however, when using setInterval(), the timer code is only inserted into the queue when there are no other code instances of that timer. This ensures that the minimum time interval for the timer code to be added to the queue is the specified interval.

      Such a rule brings two problems

   1. Some intervals are skipped

   2. The interval between code executions for multiple timers may be smaller than expected

   To avoid these two drawbacks, we can use setTimeout() to implement a repeating timer

setTimeout(function () {
            //code
            setTimeout(arguments.callee, interval);
        }, interval)

    This creates a new timer each time the function executes, and the second setTimeout() call uses agrument.callee to get a reference to the currently executing function and set another new timer. Doing this ensures that no new timers are inserted until the code execution is complete, and that the next timer code is executed with at least a specified time interval to avoid continuous running.

setTimeout(function () {
            var div = document.getElementById('moveDiv');
            var left = parseInt(div.style.left) + 5;
            div.style.left = left + 'px';
            if (left < 200) {
                setTimeout(arguments.callee, 50);
            }
        }, 50);

   Every time this timer code is executed, move a div to the right by 5px, and stop when the coordinates are greater than 200

 

 

 

 

.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326086615&siteId=291194637