Understanding JavaScript Asynchronous Programming _javascript skills

Source: Internet
Author: User
Tags event listener message queue

First, asynchronous mechanism

JavaScript's execution environment is single-threaded, and the advantage of single-threaded is that the execution environment is simple, without having to consider the annoying problems that need to be faced by multi-threaded blocking programming such as resource synchronization, deadlock, and more. But the downside is that when a task executes for a long time, the following task waits a long time. In the browser side will appear the browser suspended animation, the mouse can not respond to such situations. So, at the browser end, time-consuming operations should be performed asynchronously to avoid the browser losing its response. Asynchronous execution, unlike synchronous execution, in which the order of execution of the program is consistent and synchronized with the order of the task, each task has one or more callback functions (callback), and the previous task is not performed after the last task, but instead executes the callback function, The latter task is performed before the end of the previous task, so the sequence of execution of the program is inconsistent with the order of the task, asynchronous. Since JavaScript is single-threaded, how can it be executed asynchronously?

Second, JavaScript threading model and event-driven

JavaScript has a concurrency pattern based on the event loop. This pattern differs greatly from the C language and Java.

Concept of Run time

Stack
A function call forms a stack frame.

function f (b) {
  var a =;
  return a+b+35;
}

function g (x) {
  var m = 4;
  return f (m*x);
}

G (21);

When the function g is called, the first frame that contains the G parameter and the local variable is created. When the G function calls the F function, create the second stack frame containing the F parameter and the local variable and push to the top of the first stack frame. When F returns, the top stack frame element is ejected (only the G call is left). When the G function returns, the stack is empty.

Heap
A heap is a large, unstructured area in which objects are assigned to the heap.
Queues
A JavaScript runtime environment contains an information queue, which is a list of information that will be executed. Each message is associated with a function. When the stack is empty, a message is fetched from the message queue and processed. The processing contains the call-related functions (and therefore an initialization stack frame). When the stack is empty again, the message processing ends.
Event Loops

The name of the event loop derives from its implementation, often as follows:

while (Queue.waitformessage ()) {
 queue.processnextmessage ();
}

queue.waitformessage synchronization waits for a message.

1. Run to completion
After each message is fully processed, other messages are processed. The advantage is that when a function cannot be advanced, it can only wait for other functions to complete (and can modify the function of the data). This differs from C, for example, if a function is running on a thread, it can stop at any point to run some other code on another thread. The disadvantage of this pattern is that if a message is too long to complete, the Web application cannot handle user interactions like clicking or scrolling. This browser alleviates this with the "script takes too long to run" dialog box. A good practice to follow is to make information processing short if possible by cutting a message to a few messages.
2. Add Message
In a Web browser, events can be added at any time, an event occurs, and an event listener is bound to the event. If there is no event listening, the event is lost. Just like clicking on an element, tie the element to a fixed-point hit event. When the settimeout is invoked, a message is added to the queue when the second parameter time of the function is passed in. If there are no more messages in the queue, the message is processed immediately; however, if there is a message, the settimeout information will have to wait for other messages for processing. For this reason, the second parameter is the smallest time, not a guaranteed time.
3. Communication between several operating environments
a web worker or Cross-domain iframe has its own stack, heap, and message queue. Two different operating environments can only send messages for communication through PostMessage methods. This method adds a message to the other runtime, if the latter listens for a message event.
never block

The event loop model is an interesting attribute of JavaScript, and unlike other languages, it never blocks. Assuming that there is an instance of the browser dedicated to event scheduling (the instance can be a thread, which we can call an event-distributing thread event dispatch thread), the work of the instance is a loop that is not closed, and the event is fetched from the event queue. Handles all very event-associated callback functions (event handler). Note The callback function is run in the main thread of JavaScript, not in the event distribution thread, to ensure that event handling does not block. I/O operations through events and callbacks are a typical performance, so when the application waits for the indexed database query to return or the XHR request returns, it can still handle other things like user input.

Iii. Callback

Callbacks are the basis of JavaScript, and functions are passed as arguments. Like the following:

F1 ();
F2 ();
F3 ();

If a lot of time-consuming operations are performed in F1, and F2 needs to be performed after F1. The program can be changed to the form of a callback. As follows:

Function F1 (callback) {
  settimeout (function () {  //F1) a large number of time-consuming task code and to three results i,l,you.  Console.log ("This is Function1");  var i = "I", L = "Love" and y = "you";
    if (callback && typeof (callback) = = "function") {
      callback (i,l,y)
    ;

}} function F2 (A, B, c) {
  alert (A + "" + B + "" + C);
  Console.log ("This is function2");
}

Function F3 () {Console.log ("This is Function3");}
F1 (F2);
F3 ();      

Run Result:

This is function3 the this are function1 I love to you are
function2

In this way, we turn the synchronization operation into an asynchronous operation, and F1 does not jam the program running, which is equivalent to executing the main logic of the program first, delaying the execution of the time-consuming operation.
The benefits of callback functions are simple, lightweight (no extra libraries are required). The disadvantage is that the parts are highly coupled (coupling), the process is messy, and each task can only specify one callback function. An operation needs to go through multiple non-blocking IO operations, and each result is a callback that generates spaghetti (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. Monitoring of events

Another idea is to use event-driven mode. The execution of a task does not depend on the order of the Code, but on whether an event occurs.

Plain, non-jquery version of hooking up a event handler
var 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 I buttons ...");

The obligatory JQuery version
$ ("#clickity"). On ("click", Function (e) {
  console.log ("Alas, someone are Pressing my buttons ... ");


You can also customize events for listening, and for custom events, the content is part of another. The advantage of this approach is that it is relatively easy to understand, can bind multiple events, each event can specify multiple callback functions, and can be "decoupled" (decoupling), facilitate the implementation of modularity. The disadvantage is that the entire program becomes an event-driven type, and the running process becomes very unclear.

V. Observer model

We assume that there is a "signal center" in which a task is executed to "release" a signal to the signal center, and other tasks can "subscribe" to the Signal Center (subscribe) to know when they can begin to perform publish. This is called "Publish/Subscribe Mode" (Publish-subscribe pattern), also known as "Observer Mode" (Observer patterns).

 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 to 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;
Unsubscribe is not written, traverse topics, and then by saving the front return token, delete the specified element}) ();
  Triggered event var F2 = function (topics, data) {Console.log ("Logging:" + topics + ":" + data);
Console.log ("This is function2");
    Function F1 () {settimeout (function () {//F1 task Code Console.log ("This is Function1");
    Publish the message ' Done ' pubsub publish (' Done ', ' Hello World ');
}, 1000);
} pubsub.subscribe (' Done ', F2);

F1 (); 

The above code runs as follows:

This is function1 Logging:done:hello the world it is
function2

There are many ways to implement the observer pattern, or you can borrow the Third-party library directly. The nature of this approach is similar to "event sniffing" (The Observer pattern and custom events are very similar), but is significantly better than the latter. Observer mode is as good as decoupling with event monitoring, and there is a message center that can monitor the program well by handling the message center.

Vi. promises objects

The concept of promises is presented by members of the COMMONJS group in the PROMISES/A specification. Promises is gradually used as a way of managing callback for asynchronous operations, but they are far more useful than that for their design. Promise allows us to write code in a synchronized manner, while giving us the asynchronous execution of the code.

Function F1 () {
  var def = $. Deferred ();
  settimeout (function () {
    //F1 Task code
    console.log ("This is F1");
    Def.resolve ();
  return Def.promise ();
}

function F2 () {
  Console.log ("This is F2");
}

F1 (). then (F2);

The above code runs as follows:

This is F1 the This is
F2

The above reference is jquery to promises/a implementation, jquery also has a series of methods, specific reference: Deferred Object. About promises, it is strongly recommended to read you ' re Missing ' Promises. There are many third-party libraries to achieve promises, such as: Q, Bluebird, mmdeferred and so on. Promise (Chinese: commitment) In fact, a finite state machine, a total of three states: pending (in execution), fulfilled (execution success) and rejected (execution failure). Where pending is the initial state, fulfilled and rejected are the end states (the end state indicates that the promise life cycle has ended). The state transition relationship is: pending->fulfilled,pending->rejected. Various events, such as execution of success events, execution failure events, and so on, will be triggered as the state transitions. The following section specifically describes the state machine to achieve JS asynchronous programming.

Seven, state machine

The essence of promises is realized by the state machine, which hooks the asynchronous operation with the state change of the object, and when the asynchronous operation ends, the corresponding state change occurs, and then other actions are triggered. This is logically more logical and easier to reduce the complexity of the code than callback functions, event sniffing, publish/subscribe solutions. About promises can refer to: JS Magic Hall: Analysis of source code understanding promises/a norms.

Viii. ES6 support for asynchronous

This is a new technology that becomes part of the 2015 ECMAScript (ES6) standard. The specification of the technology is complete, but the implementation is different in different browsers, and the support in the browser is as follows.

The var f1 = new Promise (function (resolve, reject) {
  settimeout (function () {
    //F1 Task code
    console.log ("This is F1" );
    Resolve ("Success");

  };
function F2 (val) {
  Console.log (val + ":" + "This is F2");
}
Function F3 () {
  Console.log ("This is F3")
}
F1.then (F2);
F3 ();

The results of the above code in Chrome version 43 run as follows:

This is F3 the is
F1 the
success:this is F2

The above is for JavaScript asynchronous programming Understanding learning, and then there are related articles to share, do not miss Oh.

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.