Talk about the implementation of asynchronous JavaScript

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

We often say that the JS is single threaded, such as node.js Symposium on everyone says one character of JS is single threaded, so to make the JS more simple, single thread but we really understand the so-called JS? Single thread, how the asynchronous mechanism of events and should be based on these knowledge, in the "JavaScript" is not the definitive guide, I have also been confused, until I saw a foreign language, have some features, here to share with you. In the process of translation, to find that someone had translated this article, then, in some of the statements, reference. The web site: link. Later discovered that the "JavaScript programming" senior timer and cycle timer introduced, but don't think I translate this text introduces more thoroughly, think I write not good, you can view the original foreign language.

1         Under the first two examples

1.1.       Simple setTimeout 

setTimeout(function () { while (true) { } }, 1000);

setTimeout(function () { alert('end 2'); }, 2000);

setTimeout(function () { alert('end 1'); }, 100);

alert('end');

  The implementation of the results is pop ’ end’, ’ end; 1’, and then the browser feign death, is not eject the ‘ end 2’. That is to say the first setTimeout execution time is a cycle of death, this directly leads to the theoretical one second later than it functions performed in second setTimeout is blocked, the asynchronous multi thread this and we usually understand do not interfere with each other is inconsistent.

Using the method of timer

-- the initialization of a simple JS timer, after a period of time, to trigger and execute the callback function. SetTimeout returns a unique ID, use this ID to cancel the timer.

var id = setTimeout(fn,delay);


Similar to setTimeout, is not the same, every other period of time, will continue to invoke the callback FN, until cancelled

var id = setInterval(fn,delay);


-- into a timer ID, cancel timer.

clearInterval(id);

clearTimeout(id);

1.2.       Ajax request callback

Then we realized by XMLHttpRequest Ajax asynchronous request call test, the main code as follows:

var xmlReq = createXMLHTTP();//Create a XMLHttpRequest object

function testAsynRequest() {

var url = "/AsyncHandler.ashx?action=ajax";

xmlReq.open("post", url, true);

xmlReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xmlReq.onreadystatechange = function () {

if (xmlReq.readyState == 4) {

if (xmlReq.status == 200) {

var jsonData = eval('(' + xmlReq.responseText + ')');

alert(jsonData.message);

}

else if (xmlReq.status == 404) {

alert("Requested URL is not found.");

} else if (xmlReq.status == 403) {

alert("Access denied.");

} else {

alert("status is " + xmlReq.status);

}

}

};

xmlReq.send(null);

}

testAsynRequest();//A second after calling the callback function


while (true) {

}

On the server side to achieve a simple output:

private void ProcessAjaxRequest(HttpContext context)

{

string action = context.Request["ajax"];

Thread.Sleep(1000);//As a second

string jsonObject = "{\"message\":\"" + action + "\"}";

context.Response.Write(jsonObject);

}

   In theory, if the Ajax asynchronous request asynchronous callback function, it is in a single thread, so the callback function will not be other threads from ” “ and execution, is the second after the callback, it pop ‘ ajax’, but the actual situation is not the case, the callback function cannot be performed, because the browser again because the dead cycle feign death.

   According to the above two examples, summarized as follows:

The JavaScript engine is a single thread, the browser at any time only and only one thread in a running JavaScript program.

Single thread running through the JavaScript engine is meaningful, single thread ignore thread synchronization these complex issues, the problem is simplified.


2.       The JavaScript engine

  Can JS how to achieve, we explore in the next.

  In the understanding of the timer internal operations, we must be clear, triggering and execution is not the same concept, the callback function timer will be triggered at the specified delay time, but not immediately, may need to wait. All JavaScript code is executed in a thread, such as mouse clicks and timer events only in JS single thread is idle execution.

  We look at the chart, at first you might not find what or what all don't understand, but please calm down, draw out the scene in your mind

  This chart has a lot of data and information for us to understand, when you fully understand this diagram, you will asynchronous operation mechanism of JS (JavaScript engine to realize asynchronous events) have a good understanding of. This figure is one-dimensional, vertical line is in milliseconds, different areas of the JS code blue block represents the divided. For example, the first JS block is executed 18 milliseconds, mouse click event was blocked for nearly 11 ms, etc.

  Because the JavaScript engine at the same time to perform only a section of code (which is decided by the nature of the JavaScript single thread), so each JS code block to block the other asynchronous events. This means that when an asynchronous events (such as mouse clicks, timer, Ajax) occurs, the callback function of these events will be put in the queue behind awaiting execution (how to queue depends entirely on the browser, and we can ignore their internal differences, a simplified).  

  We first start from the first block of JS code, there are two timer is initialized: a 10ms setTimeout and a 10ms setInterval. timer initialization, (timer initialization after the start timing), found the setTimeout timer callback are actually in the first block of code is triggered before the end of. But here is noted, it will not execute immediately (single thread cannot do). In fact, triggering callback will be arranged in a queue, waiting for the next execution time.

  In addition, in the first block of JS code, we found a mouse click event is triggered. The mouse to click the JS callback is bound in the asynchronous queue (we never know when a user to perform this operation, so it is considered to be asynchronous) and can not be carried out immediately. Like the timer initialization, waiting for execution.

  After the execution of the initialization of JS code block, the browser will have a question: who is waiting to execute? At this time, the mouse to click the callback and setTimeout timer callback is waiting. The browser will choose a (mouse click event) and immediately execute. While the timer callback will wait for the next time.

  Note, the mouse to click the event in the process of implementation, the interval callback was first trigger, as with the setTimeout callback, waiting for execution. With the passage of time, wait until the setTimeout timer callback execution time, the setInterval callback is triggered once again, this time triggered the callback will be abandoned. If a block of code is executed, all the setInterval callback will have to queue up, once the code block is executed, the series of setInterval callback Inter will be no delay implementation. In fact, the browser setInterval is triggered callback queue waiting to execute, unless the queue setInterval callback is empty, only allow new setInterval callback to join.

  We found that, setInterval's first triggered callback executes, the setInterval callback is triggered and the row to the queue. This conveys an important message: setInterval don't care about JS is the current execution content, setInterval triggered a callback will be no difference in line.

  Finally, when the setInterval callback is executed two times, we found no JavaScript engine to execute. This means that the browser will wait for a new asynchronous events. We know, in 50ms, the setInterval callback is triggered once again, but this time nothing blocking, so the callback immediately executed.  

  In the browser, the JavaScript engine is based on event driven, this event can be seen as the browser to send all kinds of its tasks, these tasks may originate from a block of code implementation of the current, such as the call setTimeout (), also may come from the browser kernel, such as onload (), onclick (), OnMouseOver (), setTimeOut (), setInterval (Ajax), etc. If the code from the point of view, the so-called mission solid is a callback function, since “ single threaded ” reasons, these tasks can be queued, one by one, waiting to be processing engine. (this term comes from http://www.benben.cc/blog/?p=327)

3.       The JavaScript engine threads and other listener thread


Pictured above, the timer and trigger events are on time, which suggests that the JavaScript engine thread and timer triggered threading, event triggered thread are three separate threads, even though the JavaScript engine threads are blocked, the other two trigger threads are running.

  The browser kernel implementation allows multiple threads to execute asynchronously, the thread in the kernel control under the cooperate to maintain synchronization. If a browser kernel at least three resident thread: thread JavaScript engine, event triggered Http request thread, thread, below by a diagram to explain the single threaded JavaScript engine with the addition of those threads is how interactive communication. Although each browser kernel implementation details are different, but calls the principle of which is similar.


Inter thread communication: JavaScript engine to execute the code block current, such as setTimeout JS engine to add a task, the other threads can also come from the browser kernel interface elements, such as a mouse click event, the timing trigger time arrival notice, asynchronous request state change notification. From the code view task entity is a callback function, the JavaScript engine has been waiting for the arrival of the task queue. Due to the single thread, these tasks are queued, one by one engine.

GUI rendering is performed on the engine in a thread, implementation of the interface to perform the update script, such as adding nodes, delete nodes or change the node appearance update will not immediately reflected, these operations will be stored in a queue, the JavaScript engine idle time only then has the opportunity to render. Example (see this content remains to be verified, personal feel when Dom rendering, can prevent the rendering)

<div id="test">test</div>

<script type="text/javascript" language="javascript">

var i=0;

while(1) {

document.getElementById("test").innerHTML+=i++ + "<br />";

}

</script>

  This code is intended to start from 0 sequential display numbers, they will be one by one, we now look at the code, while (1) created an endless cycle, but for single threaded JavaScript engine, in the actual situation will be made into suspension response and in the browser a state of suspended animation.

  alert()The JS engine will stop execution, until the press confirm key, when JS debugging, view the current real time web page content.

4.       SetTimeout and setInterval

Back to the beginning of the article, we look at the difference between setTimeout and setsetInterval.

setTimeout(function(){

/* Some long block of code ... */

setTimout(arguments.callee,10);

},10);


setInterval(function(){

/* Some long block of code ... */

},10);

  The two segment at first glance is the same, but not this. SetTimeout code at least once every 10ms above to perform a; however, setInterval fixed every 10ms will attempt to execute a callback function, regardless of its execution state.

We summarize:

l The JavaScript engine is only one thread, forced asynchronous events waiting for execution.

l SetTimeout and setInterval in asynchronous execution, are fundamentally different.

l If a timer is blocking the execution, it will be delayed, until the next execution point (which may be longer than expected)

l The setInterval callback may be kept out, without interval (if the callback execution time exceeds a predetermined waiting value)

JavaScript programming ", according to the setInterval argument as follows:

When using setInterval (), only when any other code examples without the timer, the timer code is added to the queue. Must pay attention to two issues:

Certain interval will be skipped (away),

② Between multiple timer code execution intervals may be less than expected. Then you can take example for   difference between setTimeout and setsetInterval.


5.       Ajax asynchronous

  A lot of classmates and friends do not know, If JavaScript is a single thread, Then the XMLHttpRequest after connecting really asynchronous? In fact, the request is asynchronous, But this request is made by the browser to open a new thread request (see above), When a state change request time, If you have previously set callback, This asynchronous thread is waiting for processing queue state change events to the JavaScript engine., When a task is being processed, The JavaScript engine is always a single thread running the callback function, The specific point is single threaded onreadystatechange run the set function.

  Tip:Understanding the JavaScript engine operation is very important, especially in the large number of asynchronous events (continuous) occurs, can improve the code efficiency.

The original foreign language:

Translation reference:

Part of the sample:

Other reference:

       



Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Brent at November 13, 2013 - 2:12 PM