使用await解决异步问题的注意点总结
项目中经常需要根据接口的返回值决定下一步操作promise, async/await时比较常见的处理异步操作的方法。本文主要是结合自己当前再项目中使用async/await的场景,说明在使用过程中应该注意的问题。
使用await解决异步问题的注意点总结
项目中经常需要根据接口的返回值决定下一步操作promise, async/await时比较常见的处理异步操作的方法。本文主要是结合自己当前再项目中使用async/await的场景,说明在使用过程中应该注意的问题。
1、await命令后面的promise对象的运行结果可能是rejected, 所以最好把await命令放在try···catch代码块中。
// 好的方法,await在try···catch代码块中
async handleOk (type) {
try {
this.btnLoading = true
const res = await this.confirmDanger(type)
this.btnLoading = false
if (res.code === '0') {
this.handle_remark = ''
this.expert_check = '否'
this.$emit('updateAlarmList', 'ok')
}
} catch (e) {
this.btnLoading = false
console.log(e)
}
}
// 糟糕的方法,reject的情况下,没有异常处理
async handleOk (type) {
this.btnLoading = true
const res = await this.confirmDanger(type)
this.btnLoading = false
if (res.code === '0') {
this.handle_remark = ''
this.expert_check = '否'
this.$emit('updateAlarmList', 'ok')
}
},
如上代码是常见的点击确认按钮进行的处理操作,为防止多次点击,给按钮增加了loading,如果await命令不在try···catch代码块,promise运行结果为rejected的情况下,不会执行await后面的代码,没有对异常情况进行处理,按钮就会一直在loading状态。
2、多个await如果不存在继发关系,最好让他们同时触发
// 好的方法,两个接口同时触发
async handleOk () {
try {
this.btnLoading = true
const [res1, res2] = await Promise.all([this.handleAlarm(), this.updateAlarm()])
this.btnLoading = false
if (res1.code === '0' && res2.code === '0') {
this.remark = ''
this.handleStatus = 1
this.$emit('updateAlarmList', 'ok')
}
} catch (e) {
this.btnLoading = false
console.log(e)
}
},
// 糟糕的方法, 两个接口继发执行,比较耗时
async handleOk () {
try {
this.btnLoading = true
const res1 = await this.handleAlarm()
const res2 = await this.updateAlarm()
this.btnLoading = false
if (res1.code === '0' && res2.code === '0') {
this.remark = ''
this.handleStatus = 1
this.$emit('updateAlarmList', 'ok')
}
} catch (e) {
this.btnLoading = false
console.log(e)
}
},
如上代码中,点击确认按钮,会调用两个接口,根据两个接口的返回结果进行后续操作。这两个接口之前不存在继发关系,因此,好的方法是采用Promise.all使两个接口可以同时触发。
3、await命令只能用在async函数中,在使用迭代器处理时需要注意
async getImageUrl () {
const textPromises = this.picUrlList.map(el => {
await this.imageRedirect(el.fullUrl) // 报错,await用在普通函数
})
},
上面的函数会报错,因为将await用在普通的函数中了,但是,如果将map方法改成async函数,也会有问题。
getImageUrl () { // 这里不需要async
const textPromises = this.picUrlList.map(async el => { // 这里使用async
await this.imageRedirect(el.fullUrl)
})
},
上面的代码可能不会正常工作,因为此时的请求会并发执行,而不是继发执行。
如果想要多个请求继发执行,正确的方法是采用for循环,如下所示
async getImageUrl () {
for (let pic of picUrlList) {
await this.imageRedirect(pic.fullUrl)
}
},
如果确实希望多个请求并发执行,使用Promise.all方法,如下所示,下面两种方法效果相同
方法一
async getImageUrl () {
const textPromises = this.picUrlList.(el => {
const { data } = this.imageRedirect(el.fullUrl)
return data
})
this.urls = await Promise.all(textPromise)
},
方法二
async getImageUrl () {
const textPromises = this.picUrlList.(el => {
const { data } = this.imageRedirect(el.fullUrl)
return data
})
this.urls = []
for (const textPromise of textPromises) {
this.urls.push({
url: await textPromise
})
}
},
以上是在项目中使用await需要注意事项,包含了异常处理,多个异步操作并发执行、继发执行的场景,掌握这些注意事项,可以解决大部分异步出问题。
更多推荐
所有评论(0)