This article or from the classic three questions (what is why how to use) to analyze JavaScript asynchronous programming.

What is asynchrony

There must be asynchrony, so let’s compare.

1. Synchronization: Synchronization means that when a process executes a request, if it takes a period of time for the request to return information, the process will wait until it receives the return information before continuing to execute the request.

2. Asynchrony: Asynchrony means that the process does not need to wait forever, but continues to perform the following operations, regardless of the status of other processes. When a message is returned, the system notifies the process to process it, which improves the execution efficiency.

Maybe it’s hard to understand, but let me use an analogy. For example, if you want to invite your goddess to dinner, then you wait for her to respond and you go to dinner together (if the goddess does not respond, you do not go to dinner), this process is synchronization.

But if you invite your goddess and you go to dinner before she responds, whether she accepts the invitation or not, then it’s asynchronous.

Why asynchronous programming

As you know, JavaScript is single-threaded, so synchronizing code is likely to block tasks. If we use asynchronous programming, we can avoid blocking the execution of subsequent code.

How to use asynchronous programming

There are four main types of asynchronous programming, and we’ll look at them one by one.

The callback function

Use the simplest callback function as an example:

 function f1(callback) {
       setTimeout(function() { // the task code for f1
             callback();
       }, 1000);
 }
 f1(f2)
Copy the code

Synchronous operations are made asynchronous through the setTimeout callback function.

The advantages of the callback function are: simple, easy to understand, optimize the program execution speed;

The disadvantages are also obvious: the code is not easy to read and understand, the parts are highly coupled, and only one callback function can be specified per task.

Even more inconveniently, if one business is dependent on data from the upper business, and the upper business is dependent on data from the lower level, and we use callback to handle asynchrony, then callback hell occurs.

Second, the Promise

Promise goes some way to solving callback hell. Promise actually improves the way callback functions are written, no matter how many business dependencies there are, through multiple THEN (…) To get the data so that the code only extends vertically;

Another point is that the logic is more obvious. By extracting the asynchronous business into a single function, the entire process can be seen to be executed step by step, the dependency hierarchy is clear, and the data required is obtained at the last step of the entire code. (Assuming, of course, that the Promise is implemented in full compliance with the PromiseA+ specification)

        const p1 = Promise.resolve(1) 
        const p2 = Promise.resolve(Promise.resolve(3))
        const p3 = Promise.resolve(Promise.reject(4))
        p1.then(value= > {
            console.log('p1', value)
        })
        p2.then(value= > {
            console.log('p2', value)
        })
        p3.catch(reason= > {
            console.log('p3', reason)
        })
Copy the code

Third, the Generator

The Generator, defined in ES6, is a sequential, seemingly synchronous, asynchronous process control expression style.

Before we do that, let’s take a look at two new ES6 protocols: the iterable protocol and the iterator protocol

1. Iterable Protocol (for of loops)

Allow an object to define its iterable behavior, such as what values can be iterated over in a for of structure. Some types in JS are built-in iterables, such as strings, arrays, type arrays, Map objects, Get objects, etc. The Object type is not iterable. The reason these built-in iterables can iterate is because the @@iterator method is implemented internally, that is, the Symbol. Iterator property implements the @@iterator method on the object or its prototype chain.

Iterator protocol :(Iterator object)

Defines a standard way to produce a set of values. An object must implement the next() method to be an iterator. The next() method must return an object that should have two properties: done and value done (Boolean) False if the iterator can produce the next value in the sequence. Value Any JavaScript value returned by the iterator

3. Implement asynchrony with Generator

const fs = require('fs');
const co = require('co');
const bluebird = require('bluebird');
const readFile = bluebird.promisify(fs.readFile);

function* read() {
    yield readFile(A, 'utf-8');
    yield readFile(B, 'utf-8');
    yield readFile(C, 'utf-8');
    //....
}
co(read()).then(data= > {
    //code
}).catch(err= > {
    //code
});
Copy the code

That is, the Generator addresses vertical scaling that Promise did not.

Fourth, Async/Await

Async/Await is a new concept introduced in ES7. It combines the Promise and Generator mentioned above to implement asynchronous operations in a synchronous manner.

Let’s briefly look at some code that uses async/await:

        async function fn3() {
            try {
                const value = await fn2() // await the right side of the expression is promise, get the result promise success value
                console.log('value', value);
            } catch (error) {
                console.log('Result of failure', error)
            }
        }
        fn3()
Copy the code

As you can see, in synchronous writing, you only need to wrap asynchronous things with Promise and call them with await. There is no need to manually control next() execution like Generator.

Async/Await is currently the best asynchronous programming solution.

Five, the summary

These four asynchronous programming schemes actually iterate over time and technology.

That is, the asynchronous history of JS can be thought of as coming from callback -> promise -> generator -> async/await.

We can better understand asynchronous JavaScript programming from these four programming schemes.

Refer to the article

Asynchronous JavaScript programming

Detail the asynchronous development of JS