JS: From settimeout to say event loop model

Source: Internet
Author: User
Tags time in milliseconds

First, from the settimeout.

The SetTimeout () method is not the content defined by the ECMAScript specification, but rather belongs to the functionality provided by the BOM. View W3school definition of the SetTimeout () method, which is used to call a function or evaluate an expression after a specified number of milliseconds.

Syntax settimeout (fn,millisec), where FN represents the code to execute, either a string containing JavaScript code or a function. The second parameter, Millisec, is the time in milliseconds, which indicates how long the FN needs to be deferred for execution.

After calling the SetTimeout () method, the method returns a number that is the unique identifier of the plan execution code that can be used to cancel the timeout call.

At first my use of setTimeout () was relatively simple, and there was no deep understanding of its operating mechanism until I saw the following code

 1  var  start = new   Date;  2  setTimeout (function   () { 3  var  end = new   Date;  4  console.log (' time elapsed: ', End-start, ' Ms ' ) ; 5 }, 500 6  while  ( new  Date-start <) {}; 

In my initial knowledge of settimeout (), the delay is set to 500ms, so the output should be time elapsed:500 Ms. Because in an intuitive understanding, the JavaScript execution engine, in the execution of the above code, should be a sequence of execution from the top down, the settimeout function is executed before the while statement. In practice, however, the output is at least 1000ms delayed after the code has been run several times.

Second, according to the results to find reasons

By reading the code it is not difficult to see that the SetTimeout () method executes in the while () loop before it declares "want" to execute an anonymous function after 500ms, which is the registration of the anonymous function, which takes effect immediately after the SetTimeout () method executes. The last line of the code while loop continues to run 1000ms, and the delay time for the output of anonymous functions registered through the settimeout () method is always greater than 1000ms, indicating that the actual call to this anonymous function is blocked by the while () loop, and the actual call is in the while () The loop block does not actually execute until it is closed.

Using the timer to implement the above logic in Java, run multiple times, the output is time elapsed:501 Ms. Java's solution to timed tasks is accomplished through multithreading, where task objects are stored in the task queue and executed by a dedicated scheduling thread in a new sub-thread. When registering an asynchronous task with the schedule () method, the dispatch thread starts working immediately on the child thread, and the main thread does not block the task from running.

This is one of the big differences between JavaScript and java/c#, the single-threaded mechanism of JavaScript. In an existing browser environment, the JavaScript execution engine is single-threaded, the main thread of the statements and methods, will block the running of the scheduled task, the execution engine only after the execution of the main thread of the statement, the timing of the task will actually execute, the period of time, may be greater than the time delay set when registering the task. At this point, JavaScript is very different from the java/c# mechanism.

Three, the event cycle model

In a single-threaded JavaScript engine, how does setTimeout () work, and here's a reference to the event loop model in the browser kernel. To put it simply, there is a task queue outside of the JavaScript execution engine, and when the SetTimeout () method is called in code, the deferred method of registration is referred to the other modules of the browser kernel (in the case of WebKit, which is the WebCore module), and when the delay method reaches the trigger condition, This delay method is added to the task queue when the delay time of the setting is reached. This process is handled by other modules in the browser kernel, independent of the main thread of the execution engine, which executes when the main thread method executes, and when it reaches an idle state, it is executed sequentially from the task queue, a process that is constantly circulating, called the event loop model.

The heap (heap) and stack (stack) are generated when the main thread of the JavaScript execution engine runs. The code in the program goes into the stack to wait for execution, when the settimeout () method is called, that is, the right Webapis method in the diagram, the corresponding module of the browser kernel begins the processing of the delay method, when the delay method reaches the trigger condition, the method is added to the task queue for the callback. As long as the code in the execution engine stack finishes executing, the main thread reads the task queue and executes the callback function that satisfies the trigger condition in turn.

As an example, further explanation:

As an example of the code in the diagram, the execution engine starts executing the above code, which is equivalent to speaking of a main () method to join the execution stack. Continue to start Console.log (' Hi ') when the log (' Hi ') method into the stack, the Console.log method is a WebKit kernel support common method, rather than the previous figure Webapis involved in the method, so here log (' Hi ') The method immediately out of the stack is executed by the engine.

After the execution of the Console.log (' Hi ') statement is completed, the log () method is executed and the Hi is output. The engine continues down, adding settimeout (callback,5000) to the execution stack. The SetTimeout () method belongs to the Webapis method in the event loop model, and when the engine executes the SetTimeout () method out of the stack, the deferred function is given to the corresponding module, which is the timer module on the right of the graph.

The execution engine will settimeout out of the stack execution, the delay processing method to the WebKit Timer module processing, and then immediately continue to process the following code, then log (' SJS ') into the execution stack, then log (' SJS ') out of the stack execution, output SJS. When the execution engine executes the console.log (' SJS '), the program finishes processing, and the main () method is also stacked.

At this time after the SetTimeout method executes 5 seconds, the Timer module detects that the delay processing method reaches the trigger condition, so the delay processing method is added to the task queue. The execution engine's execution stack is empty at this point, so the engine starts polling to check if a task queue has a task to be executed, and then checks the delay method that has reached the execution condition, and then joins the execution stack with the delay method. The engine found that the delay method called the log () method, and then the log () method into the stack. Then execute the stack sequentially, output there, and empty the execution stack.

After emptying the execution stack, the execution engine will continue to poll the task queue to see if there are any tasks to execute.

IV. realization of Timer in WebKit

The

Here has been able to thoroughly understand the following code execution process, the execution engine first put the settimeout () method into the stack is executed, execute the delay method to the kernel corresponding module processing. The engine continues to process the following code, while the while statement blocks the engine for 1 seconds, while in this process the kernel Timer module has added the delay method to the task queue at 0.5 seconds, and after the engine execution stack is emptied, the engine takes the delay method into the stack and processes it, and the final output time exceeds the expected set time.

1 var New Date; 2 setTimeout (function() {3varnew  Date; 4 console.log (' time elapsed: ', End-start, ' Ms '); 5 }); 6  while (new Date-start < 1000) {};

The Webapis section mentioned in the previous event Loop Model diagram mentions DOM events, Ajax calls, and SetTimeout methods, which simply summarize them as webapis, and they also add callback functions to the task queue waiting for the engine to execute. This is a simplified description, in fact, the browser kernel to DOM events, Ajax calls and SetTimeout methods have corresponding modules to handle, WebKit kernel in the Javasctipt execution engine, there is an important module is WebCore module, HTML parsing, The calculation of CSS style is implemented by WebCore. For the three kinds of api,webcore mentioned in the diagram, Webapis provides the DOM Binding, network, timer module to handle the underlying implementation, here or continue to settimeout as an example, to see the implementation of the timer module.

The timer class is a necessary basic component of the WebKit kernel, which can be fully understood by reading the source code, and this article simplifies and analyzes its execution process.

The delay method registered by the SetTimeout () method is passed to the WebCore component timer module for processing. The key class in the timer is the Theadtimers class, which contains two important members, TIMERHEAP task queue and Sharedtimer method scheduling class. The delay method is encapsulated as a timer object, stored in the timerheap. Like the Java.util.Timer task queue, Timerheap also uses the smallest heap of data structures to sort nextfiretime as a keyword. Sharedtimer as the Timerheap scheduling class, when the timer object reaches the trigger condition, the delay method is added to the task queue mentioned in the event loop model through the interface associated with the browser platform.

Timerheap uses the smallest heap data structure, the task that expects the least delay time is executed first, and the expected delay time is the same two tasks, the order of execution is executed according to the order of registration.

1 varStart =NewDate;2SetTimeout (function(){3Console.log (' fn1 ');4}, 20);5SetTimeout (function(){6Console.log (' fn2 ');7}, 30);8SetTimeout (function(){9Console.log (' Another fn2 ');Ten}, 30); OneSetTimeout (function(){ AConsole.log (' Fn3 '); -}, 10); -Console.log (' Start while '); the  while(NewDate-start < 1000) {}; -Console.log (' End While ');

The above code output is sequentially

1  while 2  while 3 Fn3 4 DNS 5 fn2 6 Another fn2

Reprinted from alloyteam:http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout-said-the-event-loop-model/

JS: From settimeout to say event loop model

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.