Asynchronous JS (callback → Promise → async / await)

JS asynchronous programming


JS three mountains: Prototype Prototype chain scope closures, synchronous asynchronous .
They have written their own understanding of the closures before, today to sum up JS asynchronous.

Reflections (case studies from stackoverflow):

function foo(){
    var result;
    $ajax({
        url:'...',
        success:function(response){
            result=response;
            //return response;//tried this one as well
        }
    });
    return result;
}
var result=foo();

Beginner asynchronous time, there is very easy wrong place, you want to get data back from the server side, the result has been undefined.

analysis:

JavaScript is single-threaded language, but there are many js long time-consuming tasks, such as ajax request, if all were in order, the browser unresponsive often happens, so we need asynchronous form. JS All tasks can be divided into two types: synchronous tasks and asynchronous tasks .

Sync task:

Queuing performed on the main thread task, only the first task is finished, you can perform a task after;

Asynchronous tasks:

Do not enter the main thread, into the task queue task, only the task queue notify the main thread , an asynchronous tasks can be carried out, this task will enter the main thread.

Event cycle (Event Loop):

Only the execution stack all the synchronization tasks are finished , the system will read the task queue , look inside the asynchronous tasks which can be performed , then those corresponding asynchronous tasks, the end of the wait state , into the execution stack , started.

Asynchronous solution:


Here we will try to correct what the code above, several methods are as follows:

1. callback

function foo(callback){//定义函数的时候将另一个函数(回调函数)作为参数传入定义的函数中。
    $ajax({
        //...
        success:callback//异步操作执行完毕后,再执行该回调函数,确保回调在异步操作之后执行。
    });
}
function myCallback(result){
    //...
}
foo(myCallback);

The callback function itself is a name for our convention, we define it, but does not own to implement it, it will eventually carried out by other people.

Advantages: easy to understand;
disadvantages: 1. high coupling, maintenance difficulties, callback Hell; 2 each task can only specify a callback function; 3, if the order is not divided between several asynchronous operation, the same should also wait. a further operation performed on the end of the next operation.

2. Promise

function ajax(url){
    return new Promise(function(resolve,reject){
        var xhr=new XMLHttpRequest();
        xhr.onload=function(){
            resolve(this.responseText);
        };
        xhr.onerror=reject;
        xhr.open('GET',url);
        xhr.send();
    });
}
ajax('/echo/json')
    .then(function(result){...})
    .then(function(){...})
    .catch(function(){...});

ES6 provides us with a constructor Promise native, Promise represents an asynchronous operation, can be detached from objects asynchronously and a callback function, the callback function by binding .then method in this asynchronous operation, allowing us via chain Promise method invocation to solve the problem of nested callbacks, and because there is a method promise.all, allows simultaneous execution of multiple operations simple.

promise objects exist three states:

1) Fulfilled: success status
2) Rejected: failure state
3) Pending: neither successful nor the failure state, the state can be understood as the

Two important methods promise object: resolve / reject

1) resolve Promise method can change the state of the object is successful, and after passing a parameter for the subsequent success of the operation.
2) reject the object Promise method may be changed to the state of failure, while the subsequent operation of transmitting an error message to the error handling.

.then you can use chained calls, because: always returns a Promise object each execution of the method.
Further, the function then returns the value of which can be used as the parameter for subsequent operations (for example: .then (return a) .then ( console.log (a + b)))

So the question is, if the above code is an asynchronous operation throws an error, what will happen? It calls the catch method specified callback function, handle the error, and then the method specified callback function, if the operation throws an error, catch will be captured. Promise error object has a "bubble" in nature, it will always be passed to the next, until it is captured so far, that is, the error will always be captured under a catch statement.

Promise to understand the usage of the key points:

1.then Promise example of a method is the method, i.e., its role is to add callback function for the state change on Promise instance Promise.prototype, the first parameter of this method is the callback function resolved state, the second parameter (optional) is a callback function that rejected state.
2. The second chain then begins, resolve their parameters, then a return value of resolve before a return statement.
3. With regard to the implementation of the order: Promise will be executed in the instance of the time, that is, if the output function console.log statement instantiation statement of Promise, then it will first perform than in. Promise.all Promise objects passed in an array (assumed to be p1, p2), even if the running speed faster than p2 p1, Promise.all method will still result returned in the order in the array.
These easy to understand native Promise written above, use the observer pattern. Supplementary behind.

Promise of disadvantages:
1. When in an unfinished state, which can not be determined now in the stage.
2. If you do not set a callback function, internal Promise error will not be reflected to the outside.
3. You can not cancel Promise, it will be executed immediately once the new can not be canceled midway.

3.async/await:

Many people say async / await asynchronous programming is the ultimate solution,
JavaScript is async / await achieve, can not do without Promise.

var superagent=require('superagent')
function delay(){
    return new Promise(function(resolve,reject){
        setTimeout({
            resolve(42);
        },3000);
    })
}
async function getAllBooks(){
    var bookIDs=await superagent.get('/user/books');
    await delay(1000);
    return await superagent.get('/books/ids='JSON.stringify(bookIDs));
}
getAllBooks()
    .then(function(){});

The above delay () is not declared as async. In fact, Promise objects delay () itself is returned, plus without async results are the same.

Just add the async keyword before the function name, it indicates that there is an internal function asynchronous operation. This asynchronous operation returns a Promise object in front with await keywords specified. When the function is executed, the event await, will first perform content (asynchronous) behind the await expression, no longer perform the function body behind the statement. Wait until the asynchronous operation is finished, and then automatically returns to the body of the function, the function continues behind the body of the statement.

The following passage from: https://segmentfault.com/a/11 ...

async: definition of asynchronous function
1) automatically convert the functions Promise
2) When an asynchronous function call, the function returns the value of resolve is processed
3) await asynchronous internal functions can be used

await: pause function is performed asynchronously
1) When used in front of the Promise, the await completion Promise wait, and returns the result of Promise
2) await only be used with Promise, and can not be used with callback
3) await function can only be used in async in

async / await not substituted promise, because the async / await still use the underlying promise.

async function getABC(){
    let A = await getValueA(); // getValueA 花费 2 秒
    let B = await getValueB(); // getValueA 花费 4 秒
    let C = await getValueC(); // getValueA 花费 3 秒
    return A*B*C
}

Each time encounters await keyword, Promise will stop in until the end of the run, so the total cost is 2 + 4 + 3 = 9 seconds. await an asynchronous became synchronized.

async function getABC() {
    // Promise.all() 允许同时执行所有的异步函数
    let results = await Promise.all([ getValueA, getValueB, getValueC ]); 
    return results.reduce((total,value) => total * value);
}

Function total time of 4 seconds (getValueB time-consuming).

Async 的价值在于用写同步的方式写异步,1避免了阻塞,2必免写回调

转载: https://segmentfault.com/a/1190000013141641

async/await详细了解,推荐:https://segmentfault.com/a/11...

Guess you like

Origin www.cnblogs.com/liliuyu/p/12205754.html