1. 中断请求简介
最近在项目中遇到一个问题,在连续发送同一请求时,如果第二次请求比第一次请求快,那么实际显示的是第二次请求的数据,这就会造成数据和我选择的内容不一致的问题。解决的方案:在后续发送请求时,判断之前的请求是否完成(同一个接口),如果未完成则立即取消。然后在发送新的请求。
2. 中断请求原理
首先清楚axios底层调用的是XMLHttpRequest
。
中断请求底层具体是:如果该请求已被发出,XMLHttpRequest.abort()
方法将终止该请求。当一个请求被终止,它的 readyState
将被置为 XMLHttpRequest.UNSENT
(0),并且请求的 status
置为 0。
readyState
属性变为4
意味着请求已经完成,客户端不会再等待服务端的返回了,status
属性变为0
3. 中断请求两种方式
3.1 CancelToken构造函数生成cancel
函数
axios内置CancelToken
类,并且new时可以传入回调函数,回调函数接受一个参数cancel函数,CancelToken会把取消回调注入给参数callback,外部使用cancelCallback接收。
async searchCoupon() {
try {
// 重复请求时直接取消之前的请求
if (typeof this.cancelCallback === 'function') {
this.cancelCallback('Operation canceled by the user.')
this.cancelCallback = null
}
let [err, res] = await searchCoupon({
data: this.searchCouponParam,
cancelToken: new this.$axios.CancelToken(callback => (this.cancelCallback = callback))
})
if (err) throw err
this.bestCouponList = (res && res.list) || []
} catch (error) {
console.log(error)
}
},
3.2 CancelToken.source()生成取消令牌token
data:{
return {
cancelTokenSource: null //取消请求
}
}
// 优惠券检索
async couponSearch(val) {
//如果存在CancelTokenSource,手动取消请求
if (this.cancelTokenSource) {
this.cancelTokenSource.cancel('cancel by hand')
this.cancelTokenSource = null
}
const cancelToken = this.$axios.CancelToken
this.cancelTokenSource = cancelToken.source()
try {
let [err, res] = await couponSearch({
cancelToken: this.cancelTokenSource.token,
data: {
sku_ids: this.skuIds || '',
keyword: this.useCode || ''
}
})
this.searchCouponList = res.list || []
} catch (error) {
console.error(error)
}
}
4. 中断请求封装
// TODO