When talking about asynchronous programming, I will mainly from the following three aspects to summarize asynchronous programming ( Note: Special explanation: is summed up, I am also rookie, so summed up the bad, please Daniel a lot of forgiveness!) )
1. SetTimeout and SetInterval detailed analysis of the basic principles.
2. Distributed events (PUB/SUB).
3. Promise objects and deferred objects.
The next blog will be summed up settimeout and setinterval basic points, for the above three point will be divided into three blog respectively to sum up, to know the above three points of people, but not very understanding of the comprehensive knowledge point of the code farmers, no relationship, we can slowly learn, to understand, Or I summarize the incomplete or bad place can leave a message, learning is to be interactive, only to improve. Of course, for those knowledge Daniel, can also look at, if I summed up the bad words, can also make suggestions, I can learn more under!
Before studying settimeout and setinterval, we can first take a look at a small demo, in fact, the summary and research is to do more demo, because some things we look very simple, really do it when it is not so. For example, as follows:
for (var i = 1; I <= 3; i++) {
settimeout (function () {
Console.log (i);
},100);
}
If the JavaScript language is not very familiar, many people will take it for granted that the for loop prints out the 1,2,3 separately. But that's not the case, it will output 3 times 4. To understand why print three times 4, let's first understand settimeout this function, many people will think that the above settimeout means this, in 100 milliseconds after the implementation of the settimeout callback function, in fact, this understanding is wrong, In fact settimeout and setinterval really mean the following:
- SetTimeout: After the specified number of milliseconds, the functions processed by the scheduled task are added to the end of the queue.
- SetInterval: Adds a timed task handler function to the tail of the execution queue, according to the specified period (in milliseconds).
SetTimeout and setinterval are asynchronous, so we can now understand why the top loop is always 4? In fact, when the call settimeout, there will be a delay event into the queue, and then settimeout the line after the call to run the code, and then the next line of code, until there is no more code, JavaScript virtual machine will ask, there is still in the queue? If at least one event in the queue is suitable for triggering, such as the settimeout function above, the settimeout function is called. So the above code is first for loop, Loop end, and i = = 4 is incremented until no longer satisfies i<=3. So we printed 3, 4.
Let's take a look at the following function, as follows:
settimeout (function () {
Console.log ("Print me, I am executing asynchronously");
},100);
Console.log ("I'm new here, I want to do it first");
The result is: First print out "I'm new, I'm going to execute" the code, and then print "Print me, I am executing asynchronously" code.
Two: Understanding JavaScript threads.
JavaScript engines are single-threaded, and browsers run only one thread at a time.
So how does a single thread work with the browser kernel to handle these timers and corresponding browser events?
The browser kernel allows multiple threads to execute asynchronously, which work together under the control of the kernel to maintain synchronization, such as a browser with at least 3 threads, JavaScript engine threads, interface rendering threads, browser event triggering threads, and, in addition to these, some executed threads. such as HTTP request threads, these asynchronous threads can produce different asynchronous events.
Interface Render Thread:
The thread is responsible for rendering the browser HTML interface element, which is executed when the interface needs to be redrawn or because of an action that causes reflux (reflow), which is mutually exclusive to the JavaScript engine thread because the JavaScript engine runs the script Browser rendering thread is out of suspend state, such as our common is in the page Head label does not recommend JS in the header of the reason, I hope to put JS in the tail or use asynchronous loading and other operations. Therefore, updates to the interface in the script, such as dynamically adding nodes or deleting nodes, will place these events in the queue, and the JavaScript engine can only be rendered when it is idle.
Browser Event Trigger Thread:
When a user clicks an attached have a click event processor DOM element, a click event is queued, but the click event handler waits until all the currently running code has ended before executing.
For example, the following a small demo, we usually write code, especially with the original JavaScript write tab switch, often encounter the following code, such as clicking on an Li tag, want to switch to the corresponding content. Click on the event demo below. I'll use jquery here to demonstrate:
The HTML code is structured as follows:
click me 1
< li class= "container" > click me 2
< li class= "container" > click me 3
JS is as follows:
var lists = $ (". Container");
for (var i = 0, Ilen = lists.length i < Ilen; i++) {
$ (lists[i]). bind (' click ', function () {
Console.log (i); Print 3
});
}
The above code clicks, prints out 3 (not 0,1,2), the principle is same as above.
Timed Trigger Thread:
The timer counter mentioned here is not counted by the JavaScript engine, because the JavaScript engine is single-threaded and, if it is not counted in a blocking state, it must rely on external timing and trigger timing, so the timed event in the queue is also an asynchronous event.
Third: Understanding SetTimeout and SetInterval Asynchronous events:
The most basic asynchronous function of JavaScript is that settimeout and setinterval,settimeout perform the corresponding function after a certain time, which takes a callback function and a millisecond time, such as the following:
Console.log ("a");
settimeout (function () {
Console.log ("C")
}, 500);
settimeout (function () {
Console.log ("D")
}, 500);
settimeout (function () {
Console.log ("E")
}, 500);
Console.log ("B");
The console first outputs "a", "B", and after about 500 milliseconds, see "C", "D", and "E".
But if I change the first settimeout's delay time to a little or 600 milliseconds, then the print is a,b,d,e,c. You may have heard the word loop, which is used to describe how the queue works. When the asynchronous function executes, the callback function is pressed into the queue, and the JavaScript engine does not start the event loop until the asynchronous function is finished, which means that JavaScript is not multi-threaded, and the event loop is a first-in, first-out (FIFO) queue, This means that callbacks are executed in the order in which they were queued (in the same case. , but if the delay time is not the same, then will not be, as the above the case of the timing of the number of milliseconds to change the size of the output is not the same.
Four: Types of asynchronous functions
The asynchronous functions provided in a JavaScript environment are grouped into 2 broad categories: I/O functions and timing functions.
One: asynchronous I/O functions.
We all know that the creation of Nodejs is not meant to run JavaScript on the server, but because the JavaScript language is perfect for non blocking I/O. For example, a typical AJAX request, the following code:
var url = "http://localhost/setTimeout/index2.php";
var xhr=new xmlhttprequest;
Xhr.open ("Get", "http://localhost/setTimeout/index2.php", true);
Xhr.send ();
Xhr.onreadystatechange=function () {
if (xhr.readystate<4) return;
alert (Xhr.responsetext);
};
Alert ("Ajax is not finished yet?") ");
Run the results first to execute the AJAX is not finished yet? , and then executes the onreadystatechange callback function. After you execute the Send method in the AJAX function, you bind the event instead of binding the event first, and then send it?
In fact, the XHR object uses other threads, which involves a number of issues across the thread of communication, access to data across threads need to use a delegate, otherwise there will be data conflicts, the so-called delegate is actually a thread to another thread to send messages, But the XHR thread wants the delegate to trigger the onReadyStateChange event of the main thread Xhr object, and the main thread is currently busy, and it is factoring the initialization message until the initialization message is idle to perform the child thread's delegate processing. Initializing a message when it is idle means that the onReadyStateChange event is bound, so the subsequent code execution is always faster than the XHR thread. So the following Alert dialog box is executed before the onReadyStateChange event is executed. Of course the AJAX request the third parameter we can set to false, synchronous requests, generally or asynchronously, but in order to handle some special requirements, you can set up synchronization requests (note: Synchronization requests block the browser load, so if the requested data is large, consider an asynchronous request.) ), for example, some common requirements, after sending an AJAX request, to open a new window such a requirement, we all know that if the asynchronous request for Chrome and Firefox will be directly intercepted, but if I set the sync request can be implemented to send AJAX request, then open a new window.
Second: Asynchronous timing function.
We've seen that asynchronous functions are very useful for I/O operations, but we now want a function to run at some point in the future, or an animation function that will be animated at some point in the future, when we think of The settimeout and SetInterval functions in JavaScript. But SetTimeout and setinterval have the following drawbacks:
- When the same JavaScript process runs code, no JavaScript timer functions can get the code running, as shown in the demo test:
var start = new Date;
Sttimeout (function () {
var end = new Date;
Console.log ("Time:", End-start, ' Ms ');
},500);
while (new Date-start < 1000) {
}
Want to print out the above Console.log, in the browser has been refreshing to see, the first 1020ms, the second 1029ms, anyway, the result has been 1s above, that is, after the function if the execution time is very long, then settimeout code will never be executed.
2. SetInterval according to the HTML specification: within one hours delay 4-5ms such a delay. Which means it's not very accurate to use this timing.