This article introduces the JavaScript timing mechanism, to understand the JavaScript timing mechanism, it is necessary to know the operating mechanism of JavaScript.
First of all, JavaScript is a single-threaded run (JavaScript engine thread) event driver.
One, there are more than one thread in the browser
The most basic thread that is contained in a browser:
1, JavaScript engine thread.
2, Timer thread, setinterval and settimeout will trigger this thread.
3. The browser event triggers the thread, which triggers the onclick, onmousemove, and other browser events.
4, interface rendering thread, is responsible for rendering browser interface HTML elements. Note: The interface rendering thread is in a pending state while the JavaScript engine is running the script. That is, when using JavaScript to manipulate nodes in an interface, it is not immediately evident until the JavaScript engine thread is idle. (this last said)
5, HTTP request thread (AJAX request is also in it).
The above threads are under the control of the browser kernel to work together to complete the task (I do not know).
Second, the task queue
We know that JavaScript is single-threaded and that all JavaScript code runs in JavaScript engine threads. The Nanyi Teacher's article called this thread the main line and is an executive stack. (The following content is also mainly based on Nanyi Teacher's article Understanding summary.) )
These JavaScript code we can think of them as a task, these tasks have synchronization tasks and asynchronous task points. Synchronization tasks, such as variable assignment statements, alert statements, function declaration statements, and so on) are executed sequentially on the main thread, asynchronous tasks (such as browser events triggering various events triggered by threads, server responses returned using AJAX, etc.) in the task queue (or event queue) in chronological order , message queues, waiting to be executed. As long as the main thread on the execution of the task, it will go to check the task queue, see if there are queues waiting for the task, and let the queued task into the main thread execution.
For example, the following examples:
In this example, the test () function takes about 8-9 seconds to complete, so when we open this page, click on the pink Square 8 seconds ago, not immediately pop-up prompt box, and to wait until 8 seconds before the pop-up, and 8 seconds before the click a few times the pink box, 8 seconds after the pop-up several times.
When we open this page, the main thread first declares the function test, declares the variable pro, assigns the P node to Pro, then adds the Click event to the P node, specifies the callback function (hangs), and then calls the test function to execute the code. During code execution in the test function, we clicked on the P node, the browser event trigger thread detects the event, and puts the event in the task queue so that when the task on the main thread (here is the test function) is finished, the event is checked and the corresponding callback function is executed. If we click more than once, these multiple triggered events are queued in the task queue at the trigger time (you can add a click event to another element, alternately clicking on a different element to verify it).
The following are the operational mechanisms for the summarized tasks:
The operating mechanism for asynchronous execution is as follows. (This is also true for synchronous execution, because it can be considered asynchronous execution without an asynchronous task.) )
1. All synchronization tasks are performed on the main thread to form an execution stack (execution context stack).
2, there is also a "task queue" in the main thread. As long as the asynchronous task has a running result, an event is placed in the task queue.
3. Once all the synchronization tasks in the execution stack are completed, the system reads the task queue to see what events are inside. Those corresponding asynchronous tasks, then end the wait state, into the execution stack, start execution.
4. The main thread repeats the third step above.
III. events and Callback functions
When we assign an event to a DOM element, we specify a callback function so that the code executes when the event really occurs.
The callback function of the event in the main thread is suspended, and if the task queue has a corresponding event queued, the corresponding callback function is executed when the main thread detects it. We can also say that the main thread performs the asynchronous task, which is executing the corresponding callback function.
Iv. Cycle of events
The main thread checks the task queue for events in a loop, so we can draw an event loop diagram:
In the diagram above, the main thread generates heaps and execution stacks, and after the tasks in the stack are executed, the main thread examines the events that occurred in the task queue that were passed in by other threads, detects the top event, finds the callback function corresponding to the event from the pending callback function, and executes it in the execution stack, which is repeated.
Five, timer
Combining the above knowledge, the following is a discussion of timers in JavaScript: settimeout () and SetInterval ().
SetTimeout (func, T) is a time-out call that calls the function after a period of time. The process of this process in the event loop is as follows (my understanding):
The main thread finishes executing settimeout (func, t); After the statement, the callback function is Func suspended, while the timer thread starts to tick, and when the timing equals T, an event occurs, which is passed into the task queue (end timer, only time), and when the task in the main thread is finished, The main thread check task queue discovers this event and executes the pending callback function Func. The interval t We specify is only a reference value, and the real time interval depends on the amount of time spent executing the settimeout (func, T), the code after the statement, and is large. (Even if we set the T to 0, we have to go through this process).
SetInterval (func, T) is an intermittent call, calling the function every once in a while. The process in the event loop is similar to the above, but different.
SetTimeout () is after the time t after the timer thread in the task queue to add an event (note is a), and setinterval () is every time t (always timed, unless clear intermittent call) after the timer thread in the task queue to add an event, Regardless of whether the previously added event was detected and executed by the main thread. (In fact, the browser is more intelligent, the browser in processing setinterval, if found in the task queue already has queued the same ID of the setinterval of intermittent call events, the new event will be killed directly.) This means that only one intermittent call from the same ID can exist in the task queue at a time. )
For example, if you finish SetInterval (func, T), the code takes 2t, and when 2t is over, the main thread detects the first intermittent invocation event that the timer thread passes in from the task queue, and Func begins execution. When the first Func is executed, the second intermittent call event is already passed into the task queue, the main thread detects the second intermittent call event immediately, and the Func function is executed. In this case, the two executions of the Func function occur consecutively, with no time interval between them.
Here's an example:
function test () {
a = new Date ();
var b=0;
for (Var i=0;i<3000000000;i++) {
b++
}
c = new Date ();
Console.log (c-a);
}
function Test2 () {
var d = new Date (). valueof ();
var e = d-a;
Console.log (' The moment I was called was: ' +d+ ' ms ');
Alert (1);
}
SetInterval (test2,3000);
Test ();
Results:
Why do not output two of the same moment after 8.6 seconds, the reason is found in the above content.
The For loop in the execution example costs 8601ms, and in the process of executing a for loop, only one intermittent call event in the queue is queued (as described above), and the first intermittent call event goes into the main thread after 8601ms, and for this example the task queue is empty. You can pass in the intermittent call event again, so 1477462632228ms this moment the second intermittent call event (actually should be the third time) incoming task queue, because the main thread of the execution stack has been empty, so the main thread immediately put the corresponding callback function to execute, The second call is only 320ms between the first call (in fact, 8601+320=8920, almost equal to 9 seconds). We see that the third call is back to normal because there is no more code in the main thread at this time, and there is only one task, a callback function that performs an intermittent call at intervals.
Example of an intermittent invocation using settimeout ():
function test () {
a = new Date ();
var b=0;
for (Var i=0;i<3000000000;i++) {
b++
}
c = new Date ();
Console.log (c-a);
}
function Test2 () {
var d = new Date (). valueof ();
Console.log (' The moment I was called was: ' +d+ ' ms ');
SetTimeout (test2,3000);
}
SetTimeout (test2,3000);
Test ();
Results:
The time interval for every two calls is essentially the same. Think about why?
Look at one more example:
The result of this example is that the cue box pops up, and then the black border's P element appears on the page. The reason is very simple, just a word:
The interface rendering thread is in a pending state while the JavaScript engine is running the script. That is, when using JavaScript to manipulate nodes in an interface, it is not immediately evident until the JavaScript engine thread is idle.
The above is my understanding of JavaScript timing mechanism and summary, if there is a mistake, I would like to see the great God. We also hope that we can support the cloud-dwelling community.