ES6 the async and await instructions and usage

 Yesterday saw a vue tutorial, the author be sent with async / await an asynchronous request to retrieve data from the server, the code is very simple, while async / await been standardized, it is time to learn about the whole thing.

  Let me talk about async usage, it functions as a key to the front, used to indicate the function is an asynchronous function, because the meaning of async is asynchronous, which means asynchronous function to perform this function does not block execution of code behind . Write a async function

async function timeout() {
  return 'hello world';
}

   The syntax is very simple, that is in front of a function with the async keyword to indicate that it is asynchronous, how to call it that? async function is also a function, usually how we use the function on how to use it directly bracketed calls on it, in order to show that it does not block the implementation of the code behind it, we add a console.log after the async function call;

timeout function the async () { 
    return 'Hello World' 
} 
timeout (); 
the console.log ( 'though later, but first performs I');

  Open the browser console, we saw

  async function call timeout, but no output, it should not return 'hello world', do not worry, take a look timeout () to perform what is returned? The upper timeout () statement instead console.log (timeout ())

timeout function the async () { 
    return 'Hello World' 
} 
the console.log (timeout ()); 
the console.log ( 'though later, but first performs I');

  Continue to look at the console

  The original async function returns a promise object, if you want to get to promise a return value, then we should use the method, continue to modify the code

Copy the code
timeout function the async () { 
    return 'Hello World' 
} 
timeout () the then. (Result => { 
    the console.log (Result); 
}) 
the console.log ( 'though later, but first performs I');
Copy the code

  Look console

  We get to the "hello world ', while performing timeout did not perform blocking code behind, and we just said the same.

  At this point, you may have noticed that there is a console Promise resolved, this is the realization of the principle of internal async function. If there is async function returns a value when the function is called, the internal calls Promise.solve () method to convert it into an object as a promise to return, but if the timeout function throws an internal error it? We will call Promise.reject () returns a promise objects, then modify timeout function

Copy the code
timeout function the async (In Flag) { 
    IF (In Flag) { 
        return 'Hello World' 
    } {the else 
        the throw 'My God, failure' 
    } 
} 
the console.log (timeout (to true)) // call Promise.resolve () Returns the object promise. 
console.log (timeout (false)); // call Promise.reject () Returns the promise object.
Copy the code

  Console as follows:

  If the internal function throws an error, promise object has a catch methods of capture.

timeout(false).catch(err => {
    console.log(err)
})

  async keyword about it, let us consider await keyword, await the meaning of waiting, so wait for what it does, what it followed it? In fact, we can put it behind any expression, but we put more of a promise to return the object of expression. Note await keyword only put async function inside

  Now write a function that returns the object promise, the role of this function is to allow the value is multiplied by 2 after 2s

Copy the code
After return value // 2s double 
function doubleAfter2seconds (NUM) { 
    return new new Promise ((Resolve, Reject) => { 
        the setTimeout (() => { 
            Resolve (2 * NUM) 
        }, 2000); 
    }) 
}
Copy the code

  Now write a async function, which can use the await keyword, await placed behind the expression is a promise to return the object, so it can be written on the back of a function call doubleAfter2seconds

async function testResult() {
    let result = await doubleAfter2seconds(30);
    console.log(result);
}

  Call now testResult function

testResult ();

  After opening the console, 2s, the output 60. 

  Now we look at the implementation procedure code, call the testResult function, which it met await, await express wait, the code pause here, does not do a down, what is it waiting for? Other objects behind the promise is finished, then get the value of the Resolve and promise return, after getting the return value, it continues downward. Specific to our code, after encounters await, the code will be suspended, waiting for doubleAfter2seconds (30) is finished, doubleAfter2seconds (30) started promise to return, after two seconds, promise resolve up, and returned a value of 60, then await the return value only to get 60, then assigned to the result, the end of the pause, the code before proceeding to execute, execute console.log statement.

  In this function, we may not see the role of async / await, if we want to calculate the value of three numbers, then the resulting output value of it?

Copy the code
async function testResult() {
    let first = await doubleAfter2seconds(30);
    let second = await doubleAfter2seconds(50);
    let third = await doubleAfter2seconds(30);
    console.log(first + second + third);
}
Copy the code

  After 6 seconds, the console output 220, we can see that writing code is like writing asynchronous synchronization code, like, never a callback region.

  Write a real example, I had done a little feature, prepaid recharge, when the user enters a phone number, to look up the phone number where the province and city, then according to the provincial and municipal, to find possible recharge denominations, were show.

In order to simulate what the back-end interface, we create a new node project. The async create a new folder, then the new package.json npm init -y file, npm install express --save rear mounted reliance, then a new file as server.js server-side code, public folders to place as a static file, in public folder inside put index.html file, the entire directory is as follows

 

  server.js following documents, to establish the most simple web server

Copy the code
Express the require = const ( 'Express'); 
const = App Express (); // express.static provide static files is html, css, js file 
app.use (express.static ( 'public')); 

app.listen (3000, () => { 
    the console.log ( 'Start Server'); 
})
Copy the code

  Write index.html file, I am here with a vue build pages, send ajax request with axios, for simplicity, to introduce them with cdn. html part is easy, an input box, allowing users to enter the phone number, a display area of ​​the recharge amount, js part, in accordance with the requirements of vue built templates

Copy the code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Async/await</title>
    <!-- CDN 引入vue 和 axios -->
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">

        <!-- 输入框区域 -->
        <div style="height:50px">
            <input type="text" placeholder="请输入电话号码" v-model="phoneNum">
            <button @click="getFaceResult">确定</button>
            recharge denominations:
        <div>
        <-! recharge denomination display area ->
        </ div>

            <span V-for = "Item in faceList": Key = 'Item'>
                {{item}}
            </span>
        </div>
    </div>

    <!-- js 代码区域 -->
    <script>
        new Vue({
            el: '#app',
            data: {
                phoneNum: '12345',
                faceList: ["20元", "30元", "50元"]
            },
            methods: {
                getFaceResult() {

                }
            }
        })
    </script>
</body>
</html>
Copy the code

  In order to obtain the phone number input by the user, the input box to input commands to add v-model, phoneNum bind variables. Display area is bound to faceList array, v-for instructions on display, then nodemon server command line to start the server, if you have not installed nodemon, you can install it npm install -g nodemon. After a successful start, enter in the browser http: // localhost: 3000, you can see the page as follows, showing the correct

  Now let's get moving recharge face value. When you click on the OK button, we must first get the phone number in accordance with provincial and municipal, so write a method to send the request to obtain provincial and municipal, method named getLocation, accepts a parameter phoneNum, background interface called phoneLocation, when the acquired city location later, we'll send a request to obtain the face value of the recharge, so also write a method getFaceList, which takes two arguments, province and city, backstage interface faceList, add these two methods getLocation the methods below, getFaceList

Copy the code
        methods: {
            //获取到城市信息
            getLocation(phoneNum) {
               return axios.post('phoneLocation', {
                    phoneNum
                })
            },
            // 获取面值
            getFaceList(province, city) {
                return axios.post('/faceList', {
                    province,
                    city
                })
            },
            // 点击确定按钮时,获取面值列表
            getFaceResult () {
               
            }
        }
Copy the code

  现在再把两个后台接口写好,为了演示,写的非常简单,没有进行任何的验证,只是返回前端所需要的数据。Express 写这种简单的接口还是非常方便的,在app.use 和app.listen 之间添加如下代码

Copy the code
// 电话号码返回省和市,为了模拟延迟,使用了setTimeout
app.post('/phoneLocation', (req, res) => {
    setTimeout(() => {
        res.json({
            success: true,
            obj: {
                province: '广东',
                city: '深圳'
            }
        })
    }, 1000);
})

// 返回面值列表
app.post('/faceList', (req, res) => {
    setTimeout(() => {
        res.json(
            {
                success: true,
                obj:['20元', '30元', '50元']
            }
            
        )
    }, 1000);
})
Copy the code

  最后是前端页面中的click 事件的getFaceResult, 由于axios 返回的是promise 对象,我们使用then 的链式写法,先调用getLocation方法,在其then方法中获取省和市,然后再在里面调用getFaceList,再在getFaceList 的then方法获取面值列表,

Copy the code
            // 点击确定按钮时,获取面值列表
            getFaceResult () {
                this.getLocation(this.phoneNum)
                    .then(res => {
                        if (res.status === 200 && res.data.success) {
                            let province = res.data.obj.province;
                            let city = res.data.obj.city;

                            this.getFaceList(province, city)
                                .then(res => {
                                    if(res.status === 200 && res.data.success) {
                                        this.faceList = res.data.obj
                                    }
                                })
                        }
                    })
                    .catch(err => {
                        console.log(err)
                    })
            }
Copy the code

  现在点击确定按钮,可以看到页面中输出了 从后台返回的面值列表。这时你看到了then 的链式写法,有一点回调地域的感觉。现在我们在有async/ await 来改造一下。

首先把 getFaceResult 转化成一个async 函数,就是在其前面加async, 因为它的调用方法和普通函数的调用方法是一致,所以没有什么问题。然后就把 getLocation 和

getFaceList 放到await 后面,等待执行, getFaceResult  函数修改如下
Copy the code
            // 点击确定按钮时,获取面值列表
            async getFaceResult () {
                let location = await this.getLocation(this.phoneNum);
                if (location.data.success) {
                    let province = location.data.obj.province;
                    let city = location.data.obj.city;
                    let result = await this.getFaceList(province, city);
                    if (result.data.success) {
                        this.faceList = result.data.obj;
                    }
                }
            }
Copy the code

  现在代码的书写方式,就像写同步代码一样,没有回调的感觉,非常舒服。

  现在就还差一点需要说明,那就是怎么处理异常,如果请求发生异常,怎么处理? 它用的是try/catch 来捕获异常,把await 放到 try 中进行执行,如有异常,就使用catch 进行处理。

Copy the code
            async getFaceResult () {
                try {
                    let location = await this.getLocation(this.phoneNum);
                    if (location.data.success) {
                        let province = location.data.obj.province;
                        let city = location.data.obj.city;
                        let result = await this.getFaceList(province, city);
                        if (result.data.success) {
                            this.faceList = result.data.obj;
                        }
                    }
                } catch(err) {
                    console.log(err);
                }
            }
Copy the code

  Now the server is stopped, you can see the console output net Erorr, the entire program to work correctly.

Guess you like

Origin www.cnblogs.com/kangshuai/p/11617585.html