详解用async/await来处理异步(2)

再写一个真实的例子,我原来做过一个小功能,话费充值,当用户输入电话号码后,先查找这个电话号码所在的省和市,然后再根据省和市,找到可能充值的面值,进行展示。

为了模拟一下后端接口,我们新建一个node项目。 新建一个文件夹 async,然后npm init -y新建package.json文件,npm install express --save安装后端依赖,再新建server.js文件作为服务端代码, public文件夹作为静态文件的放置位置,在public文件夹里面放index.html文件,整个目录如下

详解用async/await来处理异步

server.js文件如下,建立最简单的web服务器

const express = require('express'); const app = express();// express.static 提供静态文件,就是html, css, js 文件 app.use(express.static('public')); app.listen(3000, () => { console.log('server start'); })

再写index.html文件,我在这里用了vue构建页面,用axios发送ajax请求,为了简单,用cdn引入它们。 html部分很简单,一个输入框,让用户输入手机号,一个充值金额的展示区域, js部分,按照vue的要求搭建了模版

<!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> <!-- 输入框区域 --> <div> <input type="text" placeholder="请输入电话号码" v-model="phoneNum"> <button @click="getFaceResult">确定</button> </div> <!-- 充值面值 显示区域 --> <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>

为了得到用户输入的手机号,给input输入框添加v-model指令,绑定phoneNum变量。展示区域则是绑定到faceList数组,v-for指令进行展示,这时命令行nodemon server启动服务器,如果你没有安装nodemon,可以npm install -g nodemon安装它。启动成功后,在浏览器中输入 :3000,可以看到页面如下,展示正确

现在我们来动态获取充值面值。当点击确定按钮时, 我们首先要根据手机号得到省和市,所以写一个方法来发送请求获取省和市,方法命名为getLocation, 接受一个参数phoneNum , 后台接口名为phoneLocation,当获取到城市位置以后,我们再发送请求获取充值面值,所以还要再写一个方法getFaceList, 它接受两个参数, province 和city, 后台接口为faceList,在methods 下面添加这两个方法getLocation, getFaceList

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

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

// 电话号码返回省和市,为了模拟延迟,使用了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); })

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

// 点击确定按钮时,获取面值列表 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) }) }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/459c5e2edf80230167c88a11ae9e4d78.html