Async and await

preface

First of all, let’s take it literally. Async is short for ‘asynchronous’ and await can be thought of as short for async wait. So it makes sense that async is used to declare that a function is asynchronous and await is used to wait for an asynchronous method to complete.

What does async do

We want to know what is async, because in all the tasks in the js are single thread execution, code execution order is linear, if there was a need to request the interface, the code will always card to request, such as belt interface is completed, will execute the following code, which is linear, it is obvious that this way is not very friendly, If one piece of code fails and we do not handle the exception, the code execution terminates, so the concept of an asynchronous task is introduced in JS.

Async is an ES7 specific keyword related to asynchronous operations, and is heavily associated with promises. (As for what Promise is, move on.)

The return value:

The async function returns a Promise object, and callbacks can be added using the.then method

Ex. :
    async function helloAsync(){ 
        return "helloAsync"; 
    } 
    console.log(helloAsync()) // Promise {<resolved>: "helloAsync"} 
    helloAsync().then(v= >{ 
        console.log(v); // helloAsync 
    })
Copy the code

But we don’t always use just one async. Instead, there may be await expression in async function. When async function is executed, if it encounters await, the execution will be suspended first. After the triggered asynchronous operation is completed, the execution of async function will be resumed and the parsing value will be returned.

Note:

The await keyword is valid only in async function. If you use await outside async function, you will only get a syntax error.

function testAwait(){ 
    return new Promise((resolve) = > { 
        setTimeout(function(){ 
            console.log("testAwait"); 
            resolve(); 
        }, 1000); 
    }); 
} 
async function helloAsync(){ 
    await testAwait(); 
    console.log("helloAsync"); 
} 
helloAsync(); 
// testAwait 
// helloAsync
Copy the code

What is await waiting for

“Await” is generally considered to be waiting for an async function to complete. But syntactically, await is an expression that evaluates to a Promise object or some other value (in other words, without special qualification). This ensures the independence needed to reuse blocks or move them from one place to another.

This is because an async function returns a Promise object, so await can be used to wait for the return value of an async function — it can also be said to await an async function, but be clear that it is waiting for a return value. Note that await is not just used to wait for a Promise object, it can wait for the result of any expression, so await can actually be followed by ordinary method calls or direct quantities. So the following example works perfectly

// This is a common method
function getSomething() {
    return "something";
}
// This is a method that returns a Promise
async function testAsync() {
    return Promise.resolve("hello async");
}
async function test() {
    const v1 = await getSomething();
    const v2 = await testAsync();
    console.log(v1, v2);
}
test();
Copy the code

Returns the result

As mentioned earlier, await will wait until the following Promise returns the result before executing the remaining statements following the async function.

async function fn() {
    console.log(1);
    await new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log(2);
        }, 2000);
    });
    console.log(3);
}
fn();
/ / 1
// 2 (prints after 2 seconds, and does not continue to print 3)
Copy the code

So the question is, why is 3 not printed? The rest of the async statement will not be executed until the Promise returns the await result, and the current Promise object does not return resolve or reject. So it waits and waits and waits for the rest of the statement to execute.

But if an await Promise returns a reject, it will be thrown behind the scenes as an error.

async function fn() {
    console.log(1);
    var result = await new Promise(function(resolve, reject) {
        setTimeout(function() {
            reject(2);
        }, 2000);
    });
    console.log(3);
}
fn();
/ / 1
// Uncaught (in promise) 2 (2 seconds later)
Copy the code

As shown above, an error is thrown after 2 seconds, and the number 3 is not printed, indicating that the following code is not executed. That is, if the Promise object followed by an await statement throws an error, which is a Reject state, then the whole async function stops executing.

Of course, this is not what we want, but we can make changes to the code. The value is printed as an error object so that the code does not report an error, but 3 is still not printed.

async function fn() { console.log(1); var result = await new Promise(function(resolve, reject) { setTimeout(function() { reject(2); }, 2000); }); console.log(3); } fn().catch(function(error) { console.log(error); }); // 1/2 (output after 2 seconds)Copy the code

Anonymous functions

Async can also be used to declare anonymous functions to be used in different scenarios, or to use nested async functions, such as await async, except that to use async functions after await, the function should be executed immediately and return a value.

let fn = async function() {
    let a = await (async function() {
        console.log(1);
        return 2; }) ();console.log(a);

    async function fn2() {
        return 3;
    }
    console.log(await fn2());
}
fn();
/ / 1
/ / 2
/ / 3
Copy the code

The callback function

When we write an interface call in our code, we’re going to do a chain call to.then, and if the subsequent interface uses the return value of the previous interface, we’re going to write more and more code, and we’re going to indent more and more. This is what we call the JS callback hell

Ex. :

Like this

First(function (r1) {
    Second(r1, function (r2) {
        Third(r2, function (r3) {
            console.log(r3); })})})Copy the code

There are many ways around callback hell: Promise objects, Generator functions, async functions. We’ll just say async methods here.

We just need to change the method to async and use await inside

async function request() {
    const r1 = await First()
    const r2 = await Second(r1)
    const r3 = await Third(r2)
    console.log(r3)   // R3 is what we want
}
Copy the code

The biggest benefit is that the code structure is clearer, it has better semantics, and it is faster and more enjoyable to read when writing complex business.

In fact async and await were created to make asynchronous tasks read more like synchronous code. JS is, after all, a single-threaded execution mechanism.