Understanding javascript asynchronous programming _ javascript skills

Source: Internet
Author: User
This article mainly introduces javascript asynchronous programming. You can learn javascript asynchronous programming from the ground up. If you are interested in javascript asynchronous programming, refer I. asynchronous mechanism

The execution environment of JavaScript is single-threaded. The advantage of a single thread is that the execution environment is simple, so you don't need to consider the annoying problems that need to be faced by multi-thread blocking programming such as resource synchronization and deadlock. However, the disadvantage is that when a task is executed for a long time, the subsequent tasks will wait for a long time. On the browser side, the browser is suspended, and the mouse cannot respond. Therefore, operations that take a long time on the browser end should be executed asynchronously to prevent the browser from losing its response. Asynchronous execution is different from Synchronous execution (the execution sequence of the program is the same as that of the task). Each task has one or more callback functions ), after the previous task is completed, the callback function is executed instead of the last task. The latter task is executed without the end of the previous task, therefore, the execution sequence of the program is asynchronous and inconsistent with the task arrangement order. Since Javascript is single-threaded, how can it be asynchronously executed?

Ii. Javascript thread model and event-driven

JavaScript has an event-loop-based concurrency mode. This mode is very different from C and java.

Concept of Runtime

Stack
Function calls form a stack frame.

function f(b){  var a = 12;  return a+b+35;}function g(x){  var m = 4;  return f(m*x);}g(21);

When you call function g, create the first frame that contains the g parameter and local variable. When the g function calls the f function, the Second stack frame containing the f parameter and local variable is created and pushed to the top of the first stack frame. When f is returned, the stack frame element at the top is popped up (only gcall is left ). When the g function returns, the stack is empty.

Heap
A heap is a large unstructured area where objects are allocated to the heap.
Queue
A javascript runtime environment contains an information queue, which is a list of information to be executed. Each message is associated with a function. When the stack is empty, a message is taken from the message queue for processing. This process includes calling related functions (and therefore generating an initialized stack frame ). When the stack is empty again, message processing ends.
Event Loop

The name of an event loop comes from its implementation, often as follows:

while(queue.waitForMessage()){ queue.processNextMessage();}

Queue. waitForMessageWait for a message synchronously.

1. The task is completed.
After each message is completely processed, other messages will be processed. The advantage is that when a function cannot be executed in advance, it can only wait for other functions to complete (and function operations that can modify data ). This is different from C. For example, if a function runs in one thread, it can stop at any point and run some other code in another thread. The disadvantage of this mode is that if a message is completed for too long, Web applications cannot process user interactions like clicks or scrolling. This browser can ease the dialog box "the script takes too long to run. A good practice is to make the information processing short, if possible, cut a message to several messages.
2. Add a message
In a Web browser, events can be added at any time. An event occurs and is bound to an event along with event listening. If no event listening is available, the event is lost. It is like clicking an element to bind a click event to the element. When setTimeout is called, when the second parameter time of the function is passed in, a message is added to the queue. If there is no other message in the queue, the message is processed immediately. However, if there is a message, the setTimeout information must wait for other messages for processing. For this reason, the second parameter is the minimum time, not a guaranteed time.
3. Communication between several runtime Environments
A web worker or cross-domain iframe has its own stack, heap, and message queue. Two different runtime environments can only send messages through the postMessage Method for communication. This method adds a message to another runtime if the latter listens to message events.
Never blocked

The event loop model is an interesting property of javascript. Unlike other languages, it never blocks. Assume that there is an instance in the browser dedicated to event Scheduling (this instance can be a thread, we can call it the event distribution thread event dispatch thread). The work of this instance is an endless loop, retrieve events from the event queue and process all the events associated with the callback function (event handler ). Note that the callback function runs in the main Javascript thread, rather than in the event distribution thread, to ensure that the event processing will not be blocked. Event-based and callback-based I/O operations are typical. Therefore, when an application waits for an indexed database query to return or an XHR request to return, it can still process other tasks, such as user input.

Iii. Callback

Callback is the basis of javascript, and functions are passed as parameters. As shown below:

f1();f2();f3();

If f1 executes a large number of time-consuming operations, and f2 needs to be executed after f1. The program can be changed to the callback format. As follows:

Function f1 (callback) {setTimeout (function () {// a large amount of time-consuming task code of f1 and three results I, l, you. console. log ("this is function1"); var I = "I", l = "love", y = "you"; if (callback & typeof (callback) === "function") {callback (I, l, y) ;}, 50);} function f2 (a, B, c) {alert (a + "" + B + "" + c); console. log ("this is function2");} function f3 () {console. log ("this is function3");} f1 (f2); f3 ();

Running result:

this is function3this is function1i love youthis is function2

In this way, we turn the synchronization operation into an asynchronous operation, and f1 will not block the program running, which is equivalent to executing the main logic of the program first and delaying the execution of time-consuming operations.
Callback functions are simple and lightweight (no additional libraries are required ). The disadvantage is that each part is highly coupled, and the process is messy, and each task can only specify one callback function. An operation requires multiple non-blocking IO operations. Each result is called back to generate spaghetti code.

operation1(function(err, result) {  operation2(function(err, result) {    operation3(function(err, result) {      operation4(function(err, result) {        operation5(function(err, result) {          // do something useful        })      })    })  })})

Iv. event monitoring

Another idea is to adopt the event-driven model. Task execution does not depend on the code sequence, but on whether an event occurs.

// plain, non-jQuery version of hooking up an event handlervar clickity = document.getElementById("clickity");clickity.addEventListener("click", function (e) {  //console log, since it's like ALL real world scenarios, amirite?  console.log("Alas, someone is pressing my buttons…");});// the obligatory jQuery version$("#clickity").on("click", function (e) {  console.log("Alas, someone is pressing my buttons…");});

You can also listen to custom events. Custom events are part of other content. The advantage of this method is that it is easy to understand and can be bound to multiple events. Each event can specify multiple callback functions and can be "Decoupling", which facilitates modularization. The disadvantage is that the entire program will become event-driven, and the running process will become unclear.

5. Observer Mode

We assume that there is a "signal center". When a task is completed, a signal is published to the signal center (publish). Other tasks can subscribe to the signal center) this signal to know when you can start execution. This is called publish-subscribe pattern and observer pattern ).

Var pubsub = (function () {var q = {} topics = {}, subUid =-1; // publish message q. publish = function (topic, args) {if (! Topics [topic]) {return;} var subs = topics [topic], len = subs. length; while (len --) {subs [len]. func (topic, args);} return this ;}; // subscribe to event q. subscribe = function (topic, func) {topics [topic] = topics [topic]? Topics [topic]: []; var token = (++ subUid ). toString (); topics [topic]. push ({token: token, func: func}); return token;}; return q; // If you cancel the subscription, you will not write it. traverse the topics, and then save the token returned before, delete specified Element}) (); // triggered event var f2 = function (topics, data) {console. log ("logging:" + topics + ":" + data); console. log ("this is function2");} function f1 () {setTimeout (function () {// task code console of f1. log ("this is function1"); // publish the message 'done' pubsub. publish ('done', 'Hello World') ;}, 1000) ;} pubsub. subscribe ('done', f2); f1 ();

The running result of the above Code is:

this is function1logging:done:hello worldthis is function2

There are many ways to implement the observer mode. You can also directly borrow a third-party library. The nature of this method is similar to "event listening" (The Observer mode is similar to the Custom Event), but it is significantly better than the latter. The observer mode is similar to event listening, and has a message center. by processing the message center, the program runs properly.

6. Promises object

The concept of Promises was proposed by members of the CommonJS team in the Promises/A specification. Promises is gradually used as a method for managing Asynchronous Operation callbacks, but out of their design, they are far more useful than that. Promise allows us to write code synchronously and asynchronously execute the code.

Function f1 () {var def = $. deferred (); setTimeout (function () {// task code console of f1. log ("this is f1"); def. resolve () ;}, 500); return def. promise ();} function f2 () {console. log ("this is f2");} f1 (). then (f2 );

The running result of the above Code is:

this is f1this is f2

The above references jquery's implementation of Promises/A. There are also A series of methods in jquery. For details, refer to: Deferred Object. for Promises, we strongly recommend that You read your're Missing the Point of Promises. there are also many third-party libraries that implement Promises, such as Q, Bluebird, and mmDeferred. Promise is actually a finite state machine. There are three statuses: pending (in progress), fulfilled (Execution successful), and rejected (execution failed ). Pending is the initial state, fulfilled and rejected is the end state (the end state indicates that the life cycle of promise has ended ). The status conversion relationship is pending-> fulfilled, pending-> rejected. As the status changes, various events (such as execution success events and execution failure events) are triggered ). The following section describes how to implement js asynchronous programming using a state machine.

VII. State Machine

The nature of Promises is actually implemented through the state machine, linking asynchronous operations with object state changes. When an asynchronous operation ends, the corresponding state changes, and other operations are triggered. This solution is more logical and easier to reduce Code complexity than callback functions, event listening, publishing/subscription, and other solutions. For details about Promises, refer to: JS magic Hall: analyze the source code to understand Promises/A specifications.

8. asynchronous support for ES6

This is a new technology that became part of the ECMAScript (ES6) standard in 2015. The specifications of this technology have been completed, but the implementation is different in different browsers. The support for the browser is as follows.

Var f1 = new Promise (function (resolve, reject) {setTimeout (function () {// task code console of f1. log ("this is f1"); resolve ("Success") ;}, 500) ;}); function f2 (val) {console. log (val + ":" + "this is f2");} function f3 () {console. log ("this is f3")} f1.then (f2); f3 ();

The result of the above Code running in Chrome version 43 is:

this is f3this is f1Success:this is f2

The above is an introduction to javascript asynchronous programming, and relevant articles will be shared later. Don't miss it.

Related Article

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.