async/await的简单使用
使用场景:
async/await是基于Promise对象的使用,使用在异步返回消息执行顺序的处理逻辑
问题描述:
先看一下这段代码,这段代码主要实现的功能是,获取定位地址并赋值在input框中,但是这里存在一个问题,this.isMaped = false执行完成之后,会重新渲染页面进行赋值操作。但是结果表明,input的框中并未渲染值 。
confirmAddress(){
// console.log(this.coordinate)
this.deviceDataForm.coordinate = this.coordinate.lng +',' + this.coordinate.lat
var point = new BMap.Point(this.coordinate.lng,this.coordinate.lat);//用所定位的经纬度查找所在地省市街道等信息
var gc = new BMap.Geocoder();
gc.getLocation(point, (rs)=> {
this.deviceDataForm.detailAdr = rs.address
this.deviceDataForm.deviceProvince = rs.addressComponents.province
this.deviceDataForm.deviceCity = rs.addressComponents.city
this.deviceDataForm.deviceDistrict = rs.addressComponents.district
return resolve(1)
})
//关闭弹窗
this.isMaped = false
},
原因分析:
从上面代码可以看出,代码顺序为先去getLocation获取地址,获取到结果赋值,然后执行关闭窗口。但是getLocation是异步操作的,这就表明在获取地址的同时,弹窗关闭了,但是结果并未获取到。它的执行被vue放在了下一个tick队列中。
解决方案:
这个问题是因为异步顺序出现的问题,目的是要求过去地址之后并赋值,然后再关闭弹窗。但是因为获取地址是异步的,所有关闭弹窗先执行了。这时候,就需要使用async/await搭配使用了。
先做一下简单的介绍:
- Promise:是ES6的提供的原生对象。起初我认为这个对象只用在Vue开发中,但是不管是前端是项目,只要用到js,而且是ES6以上的,都可以使用。
作用: 这个对象用做异步处理的。它完美的将异步处理做成了同步处理。
定义: 这里的resolve和reject实际上是函数,resolve代表操作成功后执行函数,可添加参数,表示成功返回的结果。reject表示操作失败后执行的函数,可添加参数,表示失败之后返回的结果。详细介绍参考菜鸟教程。
var promise1 = new Promise(function(resolve, reject) {
let flag = true;//简单表示操作成功与否,true成功,false失败
if(flag){
resolve();
}else{
reject();
}
});
var promise2 = new Promise(function(resolve) {
let flag = true;//简单表示操作成功与否,true成功,false失败
if(flag){
resolve();
}
});
- async/await:使用async/await操作返回结果基于Promise对象的。await顾名思义表示等待,即等待即将做的事情完成之后再进行下面的操作。使用await的同时一定要将函数声明为async,否则会报错 。await返回结果一定是一个Promise详细功能介绍:看这里看这里。
代码实现:
async confirmAddress(){
// console.log(this.coordinate)
this.deviceDataForm.coordinate = this.coordinate.lng +',' + this.coordinate.lat
var point = new BMap.Point(this.coordinate.lng,this.coordinate.lat);//用所定位的经纬度查找所在地省市街道等信息
var gc = new BMap.Geocoder();
//等待此功能执行成功之后再执行下一步
await new Promise(resolve => {
gc.getLocation(point, (rs)=> {
this.deviceDataForm.detailAdr = rs.address
this.deviceDataForm.deviceProvince = rs.addressComponents.province
this.deviceDataForm.deviceCity = rs.addressComponents.city
this.deviceDataForm.deviceDistrict = rs.addressComponents.district
return resolve()
})
})
this.isMaped = false
},