JavaScript is a single-threaded in-depth analysis
When the interview found that 99% of the children's shoes did not understand why JavaScript is single-threaded but it makes Ajax asynchronous send and callback requests, and settimeout also look like multi-threaded? There are also non-blocking IO, and the concept of event loop is unclear. To analyze in depth:
First look at the following code:
function foo () { ' first ' ); function () {Console.log (' second ');}), 5 for (var i = 0; i < 1000000; i++) { foo ();}
The execution results will first be all output, and then all output second, although the intermediate execution will exceed 5ms. Why?
JavaScript is single-threaded
Because JS runs in the browser, is single-threaded, each window a JS thread , since it is single-threaded, at a certain time only the specific code can be executed, and block other code. While the browser is event-driven, many of the driven in the browser are asynchronous (asynchronized) , creating events and putting them into the execution queue. The JavaScript engine is a single-threaded task queue, which you can understand as a queue of normal functions and callback functions. When an asynchronous event occurs, such as mouse click, a timer firing, or an XMLHttpRequest completing (mouse Click event occurs, Timer trigger event occurs, XMLHttpRequest completion callback trigger, etc.), Put them in the execution queue and wait for the current code to complete.
asynchronous event-driven
As mentioned earlier, the browser is event driven, and many behaviors in the browser are asynchronous (asynchronized) , such as: Mouse click event, window Size drag event, Timer trigger event, XMLHttpRequest completion callback and so on. When an asynchronous event occurs, it enters the event queue. The browser has an internal large message loop,event loop, which polls the large event queue and handles events . For example, the browser is currently busy handling the OnClick event, when another event occurs (such as window OnSize), the asynchronous event is placed in the event queue for processing, only the previous processing is complete, idle to execute the event. SetTimeout is the same, when the call, the JS engine will start timer timers, about XXMS after the execution of XXX, when the timer time, the event is placed in the main event queue waiting for processing (the browser is not busy when the real implementation).
Each browser specifically implements the main event queue is different, this is not discussed.
The browser is not a single thread
Although JS runs in the browser, is single-threaded, each window a JS thread , but the browser is not single-threaded, such as WebKit or Gecko engine, may have the following thread:
- JavaScript engine thread
- Interface Rendering Thread
- Browser Event Trigger Thread
- HTTP request Thread
Many children's shoes are confusing, if JS is single-threaded, then who is going to poll the big event loop events queue? The answer is that the browser will have a separate thread to handle this queue.
is the Ajax asynchronous request really asynchronous?
Many children's shoes are not clear, since JavaScript is a single-threaded operation, then XMLHttpRequest after the connection is really asynchronous?
The request is actually asynchronous, and the request is made by the browser to open a new thread request (see the previous browser multithreading). When the state of the request changes, if a callback was previously set, the asynchronous thread puts a status change event into the JavaScript engine's event processing queue for processing. When the browser is idle, the out-of-queue task is processed, and the JavaScript engine is always single-threaded to run the callback function. The JavaScript engine is really a single-threaded task queue that can be understood as a queue of normal functions and callback functions.
Summing up, the AJAX request is really asynchronous, the request is a new thread request by the browser, the event callback is placed in the incident loop single-threaded event queue waiting to be processed.
SetTimeout (func, 0) Why is it sometimes useful?
Writing JS more children's shoes may find that sometimes adding a settimeout (func, 0) is very useful, why? Is it analog multithreading? Wrong! As already mentioned, JavaScript is JS running in the browser, is a single thread, each window a JS thread , since it is single-threaded, SetTimeout (func, 0) where is the magic? That is to tell the JS engine, after 0ms put the Func into the main event queue, waiting for the current code to execute before execution, note: The focus is to change the code flow, the execution of the Func to wait until the current code execution is completed before execution. That's the magic of it. There are three uses for it:
- Let the browser render the current changes (many browser UI render and JS execution is placed in one thread, thread blocking will cause the interface to not update rendering)
- Re-evaluate "script is running too long" warning
- Change the order of execution
For example, in the example below, clicking on the button will show "Calculating ..." If you delete settimeout. Because the redraw event is entered into the event queue until the end of a lengthy operation, it cannot be refreshed.
<button id= ' do ' > doLongCalc!</button><div id= ' status ' ></div><div id= ' result ' ></div> $(' #do '). On (' click ',function(){ $(' #status '). Text (' Calculating ... ');//This will trigger the fired of the redraw event, but will be placed in the queue until long () is executed. //without set timeout, user'll never see "calculating ..." //long ();//Perform lengthy tasks, block //with set timeout, works as expectedSetTimeout (Long, 50);//with a timer, approximately 50ms executes long tasks after, put into the execution queue, but after redraw, according to the FIFO principle }) function Long(){ varresult = 0 for(vari = 0; i<1000; i++){ for(varj = 0; j<1000; J + +){ for(vark = 0; k<1000; k++) {result= result + i+j+k}}} $ (' #status '). Text (' calclation done ')//Have to is in here for this example. Or else it'll always run instantly. This is the same as passing it a callback}
implementation of non-blocking JS (non-blocking JavaScript)
JS in the browser needs to be downloaded, interpreted and executed in these three steps. The script in the HTML body tag is blocked. In other words, it is downloaded, interpreted, and executed sequentially. Although Chrome can implement multi-threaded parallel download external resources, such as: script file, image, frame, etc. (CSS is more complex, in IE do not block the download, but Firefox blocked download). However, because JS is single-threaded, so although the browser can speed up the JS download, but must be executed in turn. So the image image resources in chrome can be downloaded concurrently, but the external JS file concurrent download does not make much sense.
There are two ways to implement non-blocking JS (non-blocking JavaScript): 1. HTML5 2. Dynamic Loading JS
The first option is to HTML5 the defer and async Keywords:
Defer
<script type= "Text/javascript" defer src= "Foo.js" ></script>
Async
<script type= "text/javascript" async src= "Foo.js" ></script>
Then the second method is to dynamically load JS:
SetTimeout (function(){ varScript = document.createelement ("Script"); Script.type= "Text/javascript"; SCRIPT.SRC= "Foo.js"; varHead =true;//add it to the head or the tail . if(head) document.getelementsbytagname ("Head") [0].appendchild (script); Elsedocument.body.appendChild (script);},0); //another independent, dynamically loaded JS functionfunctionLoadjs (Jsurl, head, callback) {varScript=document.createelement (' script '); Script.setattribute ("Type", "Text/javascript"); if(callback) {if(script.readystate) {//IEScript.onreadystatechange =function(){ if(Script.readystate = = "Loaded" | |script.readystate= = "complete") {Script.onreadystatechange=NULL; Callback (); } }; } Else{//OthersScript.onload =function() {callback (); }; }} script.setattribute ("SRC", Jsurl); if(head) document.getelementsbytagname (' head ') [0].appendchild (script); Elsedocument.body.appendChild (script);}
Reprinted from: http://www.cnblogs.com/Mainz/p/3552717.html
[Turn]javascript is a single-threaded in-depth analysis