Four ways to do asynchronous javascript programming

  • 2020-03-30 01:46:29
  • OfStack

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 there are more than one task, you must queue up, one task in front of you is completed, the next task is executed, and so on.
The advantage of this pattern is that the implementation is relatively simple, the execution environment is relatively simple; The downside is that as long as one task is time-consuming, subsequent tasks have to wait in line, which can delay the entire process. A common example of a browser not responding (feign death) is when a piece of Javascript code runs for a long time (such as a dead loop), leaving the entire page stuck in that place and unable to perform other tasks.
To solve this problem, the Javascript language divides the execution mode of a task into two types: Synchronous and Asynchronous.
"Synchronous mode" is the mode of the previous paragraph, the latter task waits for the end of the previous task, and then execute, the execution order of the program and the order of the task is the same, synchronous; Asynchronous mode "is completely different, each task has one or more of the callback function (the callback), before the end of a task, not to perform a task, after but the callback function, after a task is before the end of a task before execution, so the program execution order the order is not consistent with the task, asynchronous.
"Asynchronous mode" is very important. On the browser side, time-consuming operations should be performed asynchronously to prevent the browser from becoming unresponsive, the best example being an 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 be executed synchronously, the server's performance will degrade dramatically and it will quickly become unresponsive.
The callback function

This is the most basic method of asynchronous programming.

Suppose there are two functions f1 and f2, the latter waiting for the result of the former.


f1();
f2();

If f1 is a time-consuming task, consider rewriting f1, writing f2 as a callback function to f1.


function f1(callback){
setTimeout(function () {
//F1 task code
callback();
}, 1000);
}

 

The executing code looks like this:

F1, f2); In this way, we change the synchronous operation into the asynchronous operation, f1 will not block the program running, it is equivalent to the main logic of the program to be executed first, and the time-consuming operation will be postponed.

Callbacks have the advantages of being simple, easy to understand, and easy to deploy. The disadvantages of callbacks are that they are not conducive to the reading and maintenance of the code, they are highly coupled to each other, their processes are messy, and they can only specify one callback function per task.

Ii. Event monitoring

Another approach is to adopt the event-driven pattern. The execution of a task depends not on the order of the code, but on whether an event occurs.

Let's take f1 and f2 again. First, bind an event to f1 (the jQuery notation used here).


f1.on('done', f2);

The above line of code means that when a done event occurs in f1, f2 is executed. Then, rewrite f1:


function f1(){
setTimeout(function () {
//F1 task code
f1.trigger('done');
}, 1000);
}

F1.trigger ('done') indicates that the done event is triggered immediately after execution to begin execution of f2.

The advantage of this approach is that it is easy to understand, can bind multiple events, each of which can specify multiple callback functions, and can be "de-coupled" to facilitate modularity. The downside is that the entire program has to become event-driven, and the running process becomes very unclear.

Publish/subscribe

The "events" in the last video can be understood as "signals."

We assume that there is a "signal center," where a task completes and "publish" a signal, and other tasks can "subscribe" to the signal center to know when they can start. This is called the publish-subscribe pattern, or observer pattern.

There are several implementations of this pattern, but the following is Ben Alman's Tiny Pub/Sub, which is a plug-in for jQuery.

First, f2 subscribs the "done" signal to the "signal center "jQuery.


jQuery.subscribe("done", f2);

Then, formula 1 is rewritten as follows:


function f1(){
setTimeout(function () {
//F1 task code
jQuery.publish("done");
}, 1000);
}

 

JQuery. Publish ("done") means that after the execution of f1, the "done" signal is issued to the "signal center "jQuery, causing the execution of f2.

In addition, f2 can also be unsubscribed after execution.


jQuery.unsubscribe("done", f2);

This approach is similar in nature to "event listening", but clearly superior to the latter. Because we can monitor the program by looking at the message center to see how many signals exist and how many subscribers each signal has.

Four, Promises object

Promises objects are a specification proposed by the CommonJS work group to provide a uniform interface for asynchronous programming.

In short, the idea is that each asynchronous task returns a Promise object with a then method that allows you to specify a callback function. For example, the callback function f2 of f1 can be written as:


f1().then(f2);

F1 will be rewritten as follows (in this case using jQuery's implementation) :


function f1(){
var dfd = $.Deferred();
setTimeout(function () {
//F1 task code
dfd.resolve();
}, 500);
return dfd.promise;
}


The advantage of writing this way is that the callback function becomes a chain, the flow of the program can be seen clearly, and there is a complete set of supporting 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). The fail (f3);
Also, it has an advantage that none of the previous three methods has: if a task is completed, add a callback function that executes immediately. So, you don't have to worry about missing an event or signal. The disadvantage of this approach is that it is relatively difficult to write and understand.


Related articles: