What are the advantages of the ultimate asynchronous processing scheme async and await compared to the traditional asynchronous processing scheme?

Write in front

statement

First of all, this blog is more subjective and only represents personal views. If you have different opinions or find that this article is wrong, you can leave a message or add my WeChat 15011177648

Basic skills required

Async and await are the new functions of es2017 (es8), and also the syntactic sugar of Promise. If you want to learn async and await, you need to understand the use of Promise first.
Portal: Promise Use
To understand the realization of Promise, you can go to my previous blog
Portal: Promise principle

A brief introduction to async and await

  • A function modified by the async keyword must return a promise object
 <script>
    (async function getPromise() {
        let pro = ajax();
        console.log(pro)
    })()
    async function ajax() {
        return 1
    }
</script>

Insert picture description here

  • If this function is modified by await again, then return the PromiseValue of the promise
<script>
    (async function getPromise() {
        let pro = await ajax();
        console.log(pro)
    })()
    async function ajax() {
        return 1
    }
</script>

Insert picture description here

  • async and await are syntactic sugar of a promise, the following two ways are equal
<script>
    (async function () {
        await request();
        console.log('后续处理')
    })()
    async function request() {
        return new Promise((resolve, reject) => {
            ajax('', () => {
                resolve()
                console.log('请求完成')
            })
        })
    }
    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>
<script>
    (function () {
        new Promise((resolve, reject) => {
            ajax('', () => {
                resolve()
                console.log('请求完成')
            })
        }).then(() => {
            console.log('后续处理');
        })
    })()
    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

With async and await, asynchronous processing becomes more elegant and easier to read

Async and await are different from previous asynchronous processing methods

I think the biggest difference between the asynchronous processing method of async and the previous asynchronous processing method is the position of the callback function.
In the previous asynchronous processing scheme, the callback function was passed into the asynchronous processing function as a parameter
. When using async, the callback function directly looks like The synchronous function is written under the previous function, and
then the previous calling method becomes a traditional call. Async and await are called async calls

Example: Traditional call

<body>
    <div>
        <span>两个接口依次调用:</span>
        <button id="twoAPI">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#twoAPI').click(() => {
        test1()
    })

    function test1() {
        ajax('no1', () => {
            test2()
        })
    }
    function test2() {
        ajax('no2')
    }

    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

Interface call time:
Traditional method calls two interface time charts in sequence
async call

<body>
    <div>
        <span>两个接口依次调用:</span>
        <button id="twoAPI">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#twoAPI').click(async function() {
        await test1();
        test2()
    })

    function test1() {
        return new Promise((resolve, reject) => {
            ajax('no1', () => resolve())
        }) 
    }
    function test2() {
        return new Promise((resolve, reject) => {
            ajax('no2', () => resolve())
        }) 
    }

    function ajax(remark, cb = () => {}) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

The interface invocation time is
The async method calls the two interface time charts in sequence
shown in the figure. It can be seen that the results of the two methods are the same, and both interfaces are called in sequence. What is the criticism of the traditional method? How is the async keyword solved?

What are the criticisms of traditional asynchronous requests? How to solve async?

Logical decentralization

For example,
there is a logic that needs to call three interfaces in sequence (the action of going to work needs to get up, wear clothes, and go out in turn)

Traditional writing

<body>
    <div>
        <span>上班</span>
        <button id="GoToWork">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#GoToWork').click(() => {
        getUp()
    })

    function getUp() {
        ajax('getUp', () => {
            getDressed()
        })
    }
    function getDressed() {
        ajax('getDressed', () => {
            goOut()
        })
    }
    function goOut() {
        ajax('getDressed', () => {
            console.log('上班去了')
        })
    }

    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

When we want to read this logic later, we will first look at the click event function of the button and see that we need to get
up before going to work, but is it over when we get up? Not necessarily, we need to find the wake-up function to see if the wake-up function does anything else, and then we will find that the wake-up function also calls the dressing function,
but is it finished after putting on the clothes? Not necessarily, we need to find the dressing function to see if the dressing function does other things, and then we will find that the dressing function also calls the out function,
but is it finished when we go out ? Not necessarily, we need to find the exit function, see if the exit function does anything else, and finally find out that after the exit function call is completed, the sentence "Go to work" is printed, and now it is really over

In this case, three things are done after a button is clicked. The logic of these three things is scattered. If you read it, you need to find them one by one. It is more troublesome. In the current example, the code is still relatively small. The number of lines of code may be dozens or hundreds of lines, and functions and functions are not necessarily next to each other, so in real cases, it is more difficult to read than this.

Combined with POS system: In the POS cash register system that our group is developing, there are many such examples. For example, a batch sales order is issued through a batch sales order. At this time, a batch sales order has been selected. , You need to call the empty temporary table in turn, associate the new approval form, and obtain the temporary table information in three steps

async

Next, use async to transform this logic

<body>
    <div>
        <span>上班</span>
        <button id="GoToWork">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#GoToWork').click(async () => {
        await getUp()
        await getDressed()
        await goOut()
        console.log('上班去了')
    })

    function getUp() {
        return new Promise((resolve) => {
            ajax('getUp', () => resolve())
        })
    }
    function getDressed() {
        return new Promise((resolve) => {
            ajax('getDressed', () => resolve())
        })
    }
    function goOut() {
        return new Promise((resolve) => {
            ajax('goOut', () => resolve())
        })
    }

    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

After this transformation, when we look at the logic again, we only need to look at the click event to know exactly what happened
Insert picture description here
after clicking the button. The logic and the order are clear at a glance, saving a lot of time to find the code.

Does not meet the principle of single responsibility, there is a problem with semantics

Traditional writing

Or the above example, let's take a closer look at the getUp method. From the function name, this method is to get up, but what exactly does this method do?
First call the get up method, then call the dress method, then call out method, and finally print a sentence "Go to work".
So according to semantics, this method should be called getUpAndGetDressedAndGoOut
because this method does these three things instead of one thing.
Conversely, if it is called getUp, then it should only do one thing to get up, that is, get up, but it does More than one thing is more contradictory

async

The async writing method basically solves this problem, the methods are originally separate, and one method only does one thing

not flexible

In the traditional method, calling getUp means calling the dressing and going out method after getUp is completed, what if we only want to call the get up method?

Traditional writing

There are two solutions

  1. Add parameters
<body>
    <div>
        <span>上班</span>
        <button id="GoToWork">click me</button>
    </div>
    <div>
        <span>只是起床</span>
        <button id="onlyGetUp">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#GoToWork').click(() => {
        getUp(true)
    })

    $('#onlyGetUp').click(() => {
        getUp(false)
    })

    function getUp(flag) {
        ajax('getUp', () => {
            flag && getDressed()
        })
    }
    function getDressed() {
        ajax('getDressed', () => {
            goOut()
        })
    }
    function goOut() {
        ajax('getDressed', () => {
            console.log('上班去了')
        })
    }

    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

You can determine whether to perform subsequent processing by adding parameters, but this will increase the complexity of the code

  1. Rewrite a function
<body>
    <div>
        <span>上班</span>
        <button id="GoToWork">click me</button>
    </div>
    <div>
        <span>只是起床</span>
        <button id="onlyGetUp">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#GoToWork').click(() => {
        getUp()
    })
    $('#onlyGetUp').click(() => {
        onlyGetUp()
    })

    function onlyGetUp() {
        ajax('getUp')
    }
    function getUp() {
        ajax('getUp', () => {
            getDressed()
        })
    }
    function getDressed() {
        ajax('getDressed', () => {
            goOut()
        })
    }
    function goOut() {
        ajax('getDressed', () => {
            console.log('上班去了')
        })
    }

    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

This can also fulfill such requirements, but adding a new method will increase unnecessary redundancy.

async

In fact, in the method of async, the method is like a component. It is called when needed, and it is not called when it is not needed. In this writing, as long as it does not call other methods

<body>
    <div>
        <span>上班</span>
        <button id="GoToWork">click me</button>
    </div>
    <div>
        <span>只是起床</span>
        <button id="onlyGetUp">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#GoToWork').click(async () => {
        await getUp()
        await getDressed()
        await goOut()
        console.log('上班去了')
    })
    $('#onlyGetUp').click(async () => {
        await getUp()
    })

    function getUp() {
        return new Promise((resolve) => {
            ajax('getUp', () => resolve())
        })
    }
    function getDressed() {
        return new Promise((resolve) => {
            ajax('getDressed', () => resolve())
        })
    }
    function goOut() {
        return new Promise((resolve) => {
            ajax('goOut', () => resolve())
        })
    }

    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

Neither add parameters nor rewrite methods

When the two interfaces are called at the same time, and subsequent operations are completed after both are completed

Example: Soak your feet and drink milk before going to bed while going to bed

Traditional writing

The traditional writing method is more strenuous when performing this kind of processing. Every time an interface is called, it is necessary to judge whether other interfaces have been completed. The
writing method is as follows

<body>
    <div>
        <span>睡觉</span>
        <button id="sleep">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#sleep').click(() => {
        drinkMilk()
        footBath()
    })

    let resultArr = [null, null]
    function drinkMilk() {
        ajax('drinkMilk', (res) => {
            resultArr[0] = res;
            for (let i = 0; i < resultArr.length; i++) {
                if (!resultArr[i]) {
                    return
                }
            }
            goToBed()
        })
    }
    function footBath() {
        ajax('footBath', (res) => {
            resultArr[1] = res;
            for (let i = 0; i < resultArr.length; i++) {
                if (!resultArr[i]) {
                    return
                }
            }
            goToBed()
        })
    }
    function goToBed() {
        ajax('goOut')
    }

    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

The request time is as shown in the figure.
Insert picture description here
However, if you want to chase a TV series before going to bed, you need to add a new function. The callback of the new function also needs to loop the resultArr.

async

async can be implemented using Promise's static method all

<body>
    <div>
        <span>睡觉</span>
        <button id="sleep">click me</button>
    </div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    $('#sleep').click(() => {
        Promise.all([drinkMilk(), footBath()]).then(() => {
            goToBed()
        })
    })

    function drinkMilk() {
        return new Promise((resolve) => {
            ajax('drinkMilk', (res) => {
                resolve(res)
            })
        })
    }
    function footBath() {
        return new Promise((resolve) => {
            ajax('footBath', (res) => {
                resolve(res)
            })
        })
    }
    function goToBed() {
        ajax('goOut')
    }

    function ajax(remark, cb = () => { }) {
        $.ajax({
            url: `https://developer.duyiedu.com/edu/groupChat/getMsgList?remark=${remark}`,
            method: 'get',
            success: cb
        })
    }
</script>

Insert picture description here
In this way, it is not necessary to go through the loop result list
and POS system every time the request is completed : in the POS cash register system that our group is developing, this is the way to print the small ticket. Before executing the printing method, you need to request the order information and configuration, Print after both requests are completed

summary

In summary, as long as the writing of async does not change the name of the interface and subsequent processing logic, there is no need to change the function that initiated the request. In traditional calls, there are many logics that are not related to the interface that will affect this interface
. It becomes a similar operation to synchronization, which reduces the difficulty of reading code, and also solves the problem of callback hell

So it ’s not too much to say that async await is the ultimate asynchronous processing solution

OK, this is all the content of this blog. If you like the content of my blog, just like it and pay attention. We will see you in the next blog.

Published 10 original articles · Like 97 · Visit 4945

Guess you like

Origin blog.csdn.net/qq_45516476/article/details/105349222
Recommended