What is the Async/Await?

Async /await is a new way to write asynchronous code. Previous methods have callback functions and promises. Async /await is implemented based on promises and cannot be used for normal callback functions. Async /await, like Promise, is non-blocking. Async /await makes asynchronous code look like synchronous code, which is part of its magic.

Async/Await syntax

**** assumes that the function getJSON returns a Promise, and that Promise has several JSON objects? We just want to call it and record the JSON and return done.

1) Use Promise:

 

    const makeRequest = () =>
        getJSON().then(data => {
            console.log(data)
            return "done"
        })

    makeRequest()
Copy the code

 

2) Async:

 

 

Const makeRequest = async () => {// await getJSON() means console.log will wait until getJSON's promise succeeds reosolve. console.log(await getJSON) return "done" } makeRequest()Copy the code

 

The difference between:

1) The function is preceded by an aync keyword. The await keyword can only be used within functions defined by AYNC. The async function implicitly returns a promise whose reosolve value is the value of the function return. (The reosolve value in the example is the string “done”) 2) Point 1 implies that we cannot use await in the outermost code because it is not inside the async function. Such as:

// Cannot use await await await makeRequest() in outermost code // this is makeRequest(). Then ((result) => {// code})Copy the code

Why Async/Await is better?

1) Using async functions can make the code much simpler. There is no need to need some THEN like Promise, no need to write anonymous functions to handle Promise’s resolve value, no need to define redundant data variables, and avoid nested code.

2) Error handling: Async/Await allows try/catch to handle both synchronous and asynchronous errors. In the following Promise example, try/catch cannot handle json.parse because it is in the Promise. We need to use.catch, which makes our error-handling code redundant. Also, our actual production code will be more complex.

Const makeRequest = () => {try {getJSON(). Then (result => {// json.parse) Console. log(data)}) Error handling asynchronous code //. Catch ((err) => {// console.log(err) //})} Catch (err) {console.log(err)}}Copy the code

With ayNC /await, catch can handle json.parse errors:

    const makeRequest = async () => {
        try {
            // this parse may fail
            const data = JSON.parse(await getJSON())
            console.log(data)
        } catch (err) {
            console.log(err)
        }
    }
Copy the code

3) Conditional statements Conditional statements are the same as error catching and can be used in Async as usual

Promise:

    const makeRequest = () => {
        return getJSON().then(data => {
            if (data.needsAnotherRequest) {
                return makeAnotherRequest(data).then(moreData => {
                    console.log(moreData)
                    return moreData
                })
            } else {
                console.log(data)
                return data
            }
        })
    }
Copy the code

Async/Await:

    const makeRequest = async () => {
        const data = await getJSON()
        if (data.needsAnotherRequest) {
            const moreData = await makeAnotherRequest(data);
            console.log(moreData)
            return moreData
        } else {
            console.log(data)
            return data
        }
    }
Copy the code

You’ve probably had a scenario where you call promise1, use the results of promisE1 to call promise2, and then use the results of both to call promise3.

    const makeRequest = () => {
        return promise1().then(value1 => {
            return promise2(value1).then(value2 => {
                return promise3(value1, value2)
            })
        })
    }
Copy the code

If promise3 does not require Value1, nesting will be easy. If you can’t stand nesting, you can avoid deep nesting by putting values 1 & 2 in promise.all, but this approach sacrifices semantics for readability. There is no reason to put Value1 and Value2 in an array other than to avoid nesting.

    const makeRequest = () => {
        return promise1().then(value1 => {
            return Promise.all([value1, promise2(value1)])
        }).then(([value1, value2]) => {
            return promise3(value1, value2)
        })
    }
Copy the code

With async/await, the code becomes surprisingly simple and intuitive.

    const makeRequest = async () => {
        const value1 = await promise1()
        const value2 = await promise2(value1)
        return promise3(value1, value2)
    }
Copy the code

5) Error stack If promises are called continuously, error handling can be cumbersome. You never know what went wrong.

    const makeRequest = () => {
        return callAPromise()
            .then(() => callAPromise())
            .then(() => callAPromise())
            .then(() => callAPromise())
            .then(() => callAPromise())
            .then(() => {
                throw new Error("oops");
            })
    }

    makeRequest().catch(err => {
        console.log(err);
        // output
        // Error: oops at callAPromise.then.then.then.then.then (index.js:8:13)
    })
Copy the code

The error stack in async/await points to the function where the error is located. In a development environment, this is not a huge advantage. However, it can be very useful when you analyze error logs in production environments. At this point, it is better to know that the error occurred in the makeRequest than in the THEN chain.

    const makeRequest = async () => {
        await callAPromise()
        await callAPromise()
        await callAPromise()
        await callAPromise()
        await callAPromise()
        throw new Error("oops");
    }

    makeRequest().catch(err => {
        console.log(err);
        // output
        // Error: oops at makeRequest (index.js:7:9)
    })
Copy the code

6) Debugging async/await makes code debugging easier. Debugging promises can be painful for two reasons:

2. If you set a breakpoint in a.then code block, use the Step Over shortcut, the debugger will not skip to the next.then because it will only skip asynchronous code.

With await/async you don’t need as many arrow functions so you can skip await statements just like debugging synchronous code.