前言
最近,在开发前端时,遇到了一个菜鸡问题,如何在一个js方法中,在包含一个异步请求的方法,然后先拿到异步请求返回来的数据,在执行下面的代码,也就是同步执行代码
一、异步请求最后才返回来请求数据,无法操作下面的代码
由代码图可知道,这个toOrderYsDetail的这个方法里,包含了Ajax的异步请求的方法getScansCode;所以,在执行到这段代码时,先发起了异步请求,但是它没有那么返回来请求的响应数据,因为js是单线程的,所以,它就先跳过了异步请求的响应,先执行下面的const req的代码了,但是因为有些参数的值,是需要拿到异步请求的响应参数来进行赋值的,因为这个请求的响应参数还没有回来,从而导致了有些参数的值为null,等到了最后面,这个异步请求的响应参数才返回来,所以,这个就导致了参数的赋值的错误。
// 数据初始化
toOrderYsDetail (index) {
const item = this.orders[index]
this.criteria.pickOrderNos = item.deliveryNo
this.criteria.matnrs = item.matnr
this.criteria.vbelns = item.vbeln
this.criteria.posnrs = item.posnr
this.criteria.clientNos = item.clientNo
// 赋值
const reqs = {
pickOrderNos: this.criteria.pickOrderNos,
matnrs: this.criteria.matnrs,
deliveryNos: this.criteria.vbelns,
iPosnrs: this.criteria.posnrs,
clientNos: this.criteria.clientNos /
}
console.log('打印请求==', reqs)
// 说明:如果在这套请求方法,则ajax请求没那么响应回来,则会先执行下面的代码
getScansCode(reqs).then(res => {
if (res.status == 0) {
this.scanCode = res.data
this.criteria.actualSalesQty = this.scanCode.salesQty
this.criteria.actualBaseQty = this.scanCode.baseQty
} else {
Notify({ type: 'danger', message: '查询失败:' + res.message })
self.loading = false
self.confirmLoading = false
}
}).catch(err => {
console.log('查询错误:' + err)
Notify({ type: 'danger', message: '查询错误:' + err })
self.loading = false
self.confirmLoading = false
})
console.log('测试===' + item)
// 响应没有回来,则先执行了这里的代码,这样,有些参数的值是null的,不对
const req = {
desliveryNo: item.deliveryNo,
clsientNo: item.clientNo,
vbseln: item.vbeln,
possnr: item.posnr,
mastnr: item.matnr,
mastnrTxt: item.matnrTxt,
basrcode: item.barcode,
bosxCode: item.boxCode,
acstualSalesQty: this.criteria.actualSalesQty,
acstualBaseQty: this.criteria.actualBaseQty,
scsanList: this.scanCode.barcode
}
this.$router.pushs({
path: '/record',
query: req
})
},
二、async和await的介绍
首先,async和await是什么呢,它们是ES7提出的基于Promise的解决异步的方案。
async它是一个加在函数前的修饰符,被定义了的话,就会返回来一个Promise对象resolve的值,可以直接then。await它是一个加在被async定义的函数内的修饰符,理解为等待,等待响应回来。
接下来,主要讲一下如何使用:
// 先定义一个异步函数,
function getOrder(){
return new Promise(()=>{
setPrice(()=>{
resolve('4秒后的价格为3元')},4000)
})
}
async function test1(){
const orderPrice = await getOrder();
console.log(orderPrice)
}
主要是在 test1()的前面加上 async 修饰符,第二个是,在getOrder()的前面加上await,即可实现同步请求了
三、使用async和await把异步请求变为同步请求
具体的操作如图所示:
// 数据初始化
// 在这里加上async
async toOrderYsDetail (index) {
const item = this.orders[index]
this.criteria.pickOrderNos = item.deliveryNo
this.criteria.matnrs = item.matnr
this.criteria.vbelns = item.vbeln
this.criteria.posnrs = item.posnr
this.criteria.clientNos = item.clientNo
// 赋值
const reqs = {
pickOrderNos: this.criteria.pickOrderNos,
matnrs: this.criteria.matnrs,
deliveryNos: this.criteria.vbelns,
iPosnrs: this.criteria.posnrs,
clientNos: this.criteria.clientNos /
}
console.log('打印请求==', reqs)
// 说明:在这里加上await,即可实现了同步请求了
await getScansCode(reqs).then(res => {
if (res.status == 0) {
this.scanCode = res.data
this.criteria.actualSalesQty = this.scanCode.salesQty
this.criteria.actualBaseQty = this.scanCode.baseQty
} else {
Notify({ type: 'danger', message: '查询失败:' + res.message })
self.loading = false
self.confirmLoading = false
}
}).catch(err => {
console.log('查询错误:' + err)
Notify({ type: 'danger', message: '查询错误:' + err })
self.loading = false
self.confirmLoading = false
})
console.log('测试===' + item)
// 响应回来了,在执行下面的代码,参数就不会为null了
const req = {
desliveryNo: item.deliveryNo,
clsientNo: item.clientNo,
vbseln: item.vbeln,
possnr: item.posnr,
mastnr: item.matnr,
mastnrTxt: item.matnrTxt,
basrcode: item.barcode,
bosxCode: item.boxCode,
acstualSalesQty: this.criteria.actualSalesQty,
acstualBaseQty: this.criteria.actualBaseQty,
scsanList: this.scanCode.barcode
}
this.$router.pushs({
path: '/record',
query: req
})
},
总结
使用async和await,可以轻松地将异步Ajax的请求,转化成同步的请求