Article collection reproduced in ( Nanyi blog)
As you may know, the execution environment of the JavaScript language is "single thread".
The so-called "single thread" means that only one task can be completed at a time. If you have multiple tasks, you must queue, complete the previous task, perform the next task, and so on.
The advantage of this model is that the implementation is relatively simple, the execution environment is comparatively pure; the disadvantage is that as long as a task takes a long time, the subsequent tasks must be queued, delaying the execution of the whole program. Common browsers are unresponsive (suspended animation), often because a certain piece of JavaScript code is running for a long time (such as a dead loop), causing the entire page to be stuck in this place and other tasks cannot be performed.
To solve this problem, the JavaScript language divides the execution pattern of a task into two types: synchronous (synchronous) and asynchronous (asynchronous).
"Synchronous Mode" is the last paragraph of the pattern, after a task to wait for the end of the previous task, and then execute, the execution order of the program is consistent with the order of the tasks, synchronous; "Asynchronous mode" is completely different, each task has one or more callback functions (callback), after the end of the previous task, Instead of performing the latter task, the callback function executes, and the latter task executes at the end of the previous task, so the order of execution of the program is inconsistent and asynchronous with the order in which the task is ordered.
The asynchronous pattern is important. On the browser side, a lengthy operation should be performed asynchronously to avoid the browser losing its response, and the best example is the Ajax operation. On the server side, "asynchronous mode" is even the only mode, because the execution environment is single-threaded, and if all HTTP requests are allowed to execute synchronously, the server's performance will drop sharply and will soon lose its response.
This article summarizes the 4 methods of "Asynchronous mode" programming, which allows you to write JavaScript programs that are more structured, better performing, and easier to maintain.
First, the callback function
This is the most basic method of asynchronous programming.
Assume there are two functions F1 and F2, which wait for the result of the former execution
F1 (); F2 ();
If F1 is a time-consuming task, consider rewriting F1 and writing F2 as the F1 callback function.
Function F1 (callback) { setTimeout (function () { //F1 task Code callback (); }, 1000);}
The execution code becomes the following: F1 (F2);
In this way, we turn the synchronous operation into an asynchronous operation, and the F1 does not clog the program, which is equivalent to executing the main logic of the program and delaying the execution of the time-consuming operation.
The advantages of the callback function are simple, easy to understand and deploy, the disadvantage is that it is not conducive to the reading and maintenance of the code, highly coupled between the parts (coupling), the process will be confusing, and each task can only specify a callback function.
Second, event monitoring
Another way of thinking 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.
Take F1 and F2 as an example. First, bind an event for F1 (the jquery notation used here).
F1.on (' Done ', F2);
The above line of code means that when a done event occurs on F1, the F2 is executed. Then, rewrite the F1:
Function F1 () { setTimeout (function () { ///F1 Task code f1.trigger (' done '); }, 1000);}
F1.trigger (' Done ') indicates that when execution is complete, the Do event is immediately triggered to begin execution of F2.
The advantages of this method are relatively easy to understand, can be bound to multiple events, each event can specify multiple callback functions, and can be "decoupling" (decoupling), is conducive to the implementation of modularity. The downside is that the entire program becomes event-driven, and the running process becomes unclear.
Third, publish/Subscribe
The "events" in the previous section can be fully understood as "signals".
We assume that there is a "signal center" in which a task executes, a signal is "released" (publish) to the signal center, and other tasks can "subscribe" to the Signal Center (subscribe) to know when they can start executing. This is called the "Publish/Subscribe Mode" (Publish-subscribe pattern), also known as the "Observer Mode" (Observer pattern).
There are several implementations of this pattern, with Ben Alman's tiny Pub/sub, which is a plugin for jquery.
First, F2 subscribes to "done" signals to the signal center jquery.
Jquery.subscribe ("Done", F2);
The F1 then overwrites the following:
Function F1 () { setTimeout (function () { ///F1 Task code jquery.publish ("Done"); }
Jquery.publish ("done") means that after the completion of the F1 execution, the "Do" signal is released to the Signal center jquery, triggering the execution of the F2.
In addition, F2 can also unsubscribe (unsubscribe) Once the execution is complete.
Jquery.unsubscribe ("Done", F2);
This method is similar in nature to "event monitoring", but is significantly better than the latter. Because we can monitor the operation of the program by looking at the message center to see how many signals exist, how many subscribers each signal has.
Iv. promises objects
The promises object is a specification proposed by the COMMONJS workgroup to provide a unified interface for asynchronous programming.
Simply put, the idea is that each asynchronous task returns an promise object that has a then method that allows you to specify a callback function. For example, F1 's callback function, F2, can be written as:
F1 (). then (F2);
F1 is going to rewrite the following (the implementation of jquery is used here):
Function F1 () { var DFD = $. Deferred (); SetTimeout (function () { //F1 Task Code dfd.resolve (); }; return dfd.promise; }
The advantage of this writing is that the callback function becomes a chain-like notation, the process of the program can be seen very clearly, and there is a complete set of methods, can achieve many powerful functions.
For example, specify multiple callback functions:
F1 (). Then (F2). then (F3);
For example, specify the callback function when an error occurs:
F1 (). Then (F2). Fail (F3);
Moreover, it has the advantage of having none of the previous three methods: if a task is completed and a callback function is added, the callback function executes immediately. So you don't have to worry about missing an event or signal. The disadvantage of this method is that it is relatively difficult to write and understand.