JS Asynchronous processing working mechanism
On a basic level, it is important to understand how JavaScript timers work. The execution of timers is often different from our intuitive imagination, because the JavaScript engine is single-threaded. Let's get to know how the following three functions control a timer.
var id = setTimeout(fn, delay);
-Initializes a timer and executes after the specified time interval. The function returns a unique flag ID (number type) that we can use to cancel the timer.
var id = setInterval(fn, delay);
-Similar to settimeout, but it is a continuous call to a function (interval is the delay parameter) until it is canceled.
clearInterval(id);
, clearTimeout(id);
-Use the Timer ID (the return value of SetTimeout and SetInterval) to cancel the occurrence of the timer callback
In order to understand the intrinsic execution principle of timers, there is an important concept that needs to be explored: The delay of a timer is not guaranteed. Since all JavaScript code is executed in one thread, all asynchronous events (for example, mouse clicks and timers) are executed only if they have an opportunity to execute. Use a good chart to illustrate:
There is a lot of information to understand in this diagram, and if you fully understand them, you will have a good idea of how the JavaScript engine implements asynchronous events. This is a one-dimensional icon: The vertical direction represents the time, and the blue block represents the JavaScript code execution block. For example, the first JavaScript code execution block takes about 18ms, the mouse click triggers the code execution block needs 11ms, and so on.
Since the JavaScript engine executes only one code at a time (this is due to the nature of the JavaScript single thread), each JavaScript code execution block "blocks" the execution of other asynchronous events. This means that when an asynchronous event occurs (for example, a mouse click, a timer is triggered, or an AJAX asynchronous request), the callback functions of these events will be queued at the end of the execution queue (in fact, the way the queue is different depending on the browser, so here is just a simplification);
Starting with the first JavaScript execution block, two timers are initialized in the first execution block: a 10ms setTimeout()
and a 10ms setInterval()
. Depending on when and where the timer is initialized (the timer starts when it is initialized), the timer is actually triggered before the first block of code is finished executing. However, the function that is bound by the timer does not execute immediately (the reason for not being immediately executed is that JavaScript is single-threaded). In fact, the deferred function is queued at the end of the execution queue, waiting for the next appropriate time to execute.
In addition, in the first JavaScript execution block we see a "mouse click" Event happening. A JavaScript callback function is bound to this asynchronous event (we never know when the user will execute the (click) event, so it is assumed to be asynchronous), the function will not be executed immediately, like the above timer, it would be queued at the end of the execution queue, waiting for the next appropriate time to execute.
When the first JavaScript execution block finishes executing, the browser immediately asks a question: which function (statement) is waiting to be executed? At this point, a "mouse click event handler" and a "timer callback function" are waiting to be executed. The browser chooses one (in effect, the "handler for mouse click event", since it is known to be an advanced team) to execute immediately. The timer callback function waits for the next appropriate time to execute.
Note that when the "mouse click event handler" is executed, setInterval
the callback function is triggered for the first time. setTimeout
like the callback function, it will be queued to the end of the execution queue for execution. However, it is important to note that the setInterva
first trigger when the L callback function is triggered the second time (the setTimeout
function is still executing) is setInterval
discarded. when a very long code block executes, it is possible to put all the setInterval
callback functions behind the execution queue, and after the code block executes, the result is a large string of setinterval callback functions waiting to be executed, and there is no interval between the functions until all is done. So, the browser tends to be when no more interval
processing functions are queued and then the next handler is discharged to the end of the queue (this is due to the problem of the interval).
We can see that when the third setInterval
callback function is triggered, the previous SetInterval callback function is still executing. This illustrates a very important fact: it setInterval
does not consider what is currently being done, and all of the blocked functions are queued to the tail of the queue. This means that the time interval between the two setinterval callback functions is sacrificed (reduced).
Finally, when the second setInterval
callback function finishes executing, we can see that no program is waiting for the JavaScript engine to execute. This means that the browser is now waiting for a new asynchronous event to occur. At 50ms, when a new setInterval
callback function is triggered again, no execution block is blocking its execution. So it will be executed immediately.
Let's use an example to illustrate setTimeout
setInterval
the difference between:
SetTimeout (function () {
/* Some long block of code ... * *
SetTimeout (arguments. callee, 10);
}, 10);
SetInterval (function () {
/* Some long block of code ... * *
}, 10);
These two codes are no different at first glance, but they are not. The interval between the execution of the settimeout callback function and the last execution is at least 10ms (possibly more, but not less than 10ms), and the callback function of SetInterval will attempt to execute every 10ms, regardless of whether the last execution was completed.
Here we learned a lot of knowledge, summed up:
- The JavaScript engine is single-threaded, forcing all asynchronous events to be queued for execution
setTimeout
And setInterval
is fundamentally different when executing asynchronous code.
- If a timer is blocked and cannot be executed immediately, it will delay execution until the next possible point in time is executed (longer than expected)
- If
setInterval
the execution time of the callback function is long enough (longer than the specified time interval), they are executed consecutively and have no time interval between them.
JS asynchronous processing working mechanism