I. What is a timer?
JS provides some native ways to delay execution of a piece of code. Here's a brief introduction
setTimeout
: Set a timer to execute a function or code snippet after the timer expiresvar timeoutId = window.setTimeout(func[, delay, param1, param2, ...]); var timeoutId = window.setTimeout(code[, delay]);
Timeout Id: Timer ID
func: Delayed function
Code: A code string that is executed after delay. It is not recommended to use a principle similar to eval()
delay: delay time (in milliseconds), default value is 0
param1,param2: Parameters passed to delayed functions, supported by IE9 or above
setInterval
: Repeated calls to a function or code segment at regular intervalsvar intervalId = window.setInterval(func, delay[, param1, param2, ...]); var intervalId = window.setInterval(code, delay);
intervalId: ID of repeated operations
func: Delayed call function
code: code snippet
delay: delay time, no default value
setImmediate: Execute the specified function (implemented only in IE10 and Node 0.10 +) immediately after the browser has completed the current operation, similar to setTimeout(func, 0)
var immediateId = setImmediate(func[, param1, param2, ...]); var immediateId = setImmediate(func);
immediateId: Timer ID
func: Callback
requestAnimationFrame
: Designed specifically for high performance frame animation APIļ¼But you can't specify the delay time, but depend on the refresh frequency of the browser (frame)var requestId = window.requestAnimationFrame(func);
func: Callback
Four kinds of JS timers are briefly introduced above, and this article will mainly introduce two kinds of timers commonly used: setTimeout and setInterval.
2. Raise a chestnut
Basic Usage
// What does the following code output after execution? var intervalId, timeoutId; timeoutId = setTimeout(function () { console.log(1); }, 300); setTimeout(function () { clearTimeout(timeoutId); console.log(2); }, 100); setTimeout('console.log("5")', 400); intervalId = setInterval(function () { console.log(4); clearInterval(intervalId); }, 200); // Output: 2, 4, 5
The difference between setInterval and setTimeout?
// What does the block of code that executes in front of it output? setTimeout(function () { console.log('timeout'); }, 1000); setInterval(function () { console.log('interval') }, 1000); // Output timeout once, interval every 1S /*--------------------------------*/ // What's the difference between setInterval and setInterval simulation through setTimeout? var callback = function () { if (times++ > max) { clearTimeout(timeoutId); clearInterval(intervalId); } console.log('start', Date.now() - start); for (var i = 0; i < 990000000; i++) {} console.log('end', Date.now() - start); }, delay = 100, times = 0, max = 5, start = Date.now(), intervalId, timeoutId; function imitateInterval(fn, delay) { timeoutId = setTimeout(function () { fn(); if (times <= max) { imitateInterval(fn ,delay); } }, delay); } imitateInterval(callback, delay); intervalId = setInterval(callback, delay);
If it is setTimeout and setInterval, they are only different in the number of executions, setTimeout and setInterval.
The difference between setInterval and setInterval simulated by setTimeout is that setTimeout calls the next timer only after the callback is completed, while setInterval inserts a callback event into the event queue when the specified time is reached, regardless of the execution of the callback function, so it chooses to select When it comes to the way the timer works, do you need to consider whether setInterval's features will have any impact on your business code?
Who is faster than setTimeout(func, 0) and setImmediate(func)? (This test was written just for curiosity)
console.time('immediate'); console.time('timeout'); setImmediate(() => { console.timeEnd('immediate'); }); setTimeout(() => { console.timeEnd('timeout'); }, 0);
Testing in Node.JS v6.7.0 found setTimeout executed earlier
Interview questions
What is the result of the following code?
// Topic 1 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){} alert('end'); /*--------------------------------*/ // Title II for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 0); } /*--------------------------------*/ // Topic 3 var obj = { msg: 'obj', shout: function () { alert(this.msg); }, waitAndShout: function() { setTimeout(function () { this.shout(); }, 0); } }; obj.waitAndShout();
The answer to the question will be answered later.
3. Working Principle of JS Timer
Before explaining the answers to the above questions, let's look at how the timer works. Here's a reference. How JavaScript Timers Work An example is given to illustrate the working principle of the timer, which is a simple version of the schematic diagram.
In the figure above, the number on the left represents the time in milliseconds; the text on the left represents the actions that are waiting to be executed after an operation has been completed, and the browser asks which operations are waiting to be executed in the current queue; the blue box represents the code block being executed; and the text on the right represents what asynchronous events occur during the code running. The general flow chart is as follows:
At the beginning of the program, a JS code block is executed for about 18 ms, and three asynchronous events are triggered during execution, including a setTimeout, a mouse click, and a setInterval.
The first setTimeout runs first, with a delay of 10 ms. Later, the mouse event appears. The browser inserts a click callback function into the event queue. Later, setInterval runs. After 10 ms arrival, setTimeout inserts a setTimeout callback into the event queue.
When the first block of code is executed, the browser looks at what events are waiting in the queue and pulls out the code at the front of the queue to execute.
When the browser processes the mouse click callback, setInterval checks the arrival delay time again, and he inserts an interval callback into the event queue, which is then inserted into the queue every other specified delay time.
After the browser has executed the code of the current queue head, the event of the current queue head will be taken out again to execute.
Here is a simple description of the principle of the timer. The actual process is more complicated than this.
IV. Question Answers
Well, let's look at the answers to the above questions.
Topic 1
alert will never execute, because JS is single-threaded, and the callback of the timer will wait until the task currently being executed is completed, while(t) {} goes directly into the dead loop and occupies the thread all the time without giving the callback function the opportunity to execute.
Question 2
The code will output 5555 55 for the same reason. When i = 0, a timer is generated to insert the callback into the event queue and execute immediately when there is no task in the current queue, while the for loop is executing, so the callback is shelved. When the for loop is completed, there are five callback functions in the queue, and they will all perform console.log(i) operation. Because there is no block scope in the current js code, the value of I is always 5 after the end of the for loop, so the code will output 5.5.
Question 3
This problem involves the direction of this. The code invoked by setTimeout() runs in a completely separate execution environment from its function. This will result in the keyword of this in these codes pointing to the window (or global) object. There is no shout method in the window object, so the error will be reported. The modification scheme is as follows:
var obj = { msg: 'obj', shout: function () { alert(this.msg); }, waitAndShout: function() { var self = this; // Here we assign this to a variable setTimeout(function () { self.shout(); }, 0); } }; obj.waitAndShout();
V. Points needing attention
setTimeout has a minimum time interval limitation. HTML5 standard is 4 ms, less than 4 ms is processed according to 4 ms, but the minimum time interval for each browser is different.
Because the JS engine has only one thread, it will force asynchronous event queuing.
If setInterval's callback execution time is longer than the specified delay, setInterval executes one after another without intervals.
The direction problem of this can be solved by bind function, defining variable and arrow function.
VI. Reference
Blog address: ssh.today Welcome your attention