背景
目前项目有2种情景需要取消请求
- 组件销毁时,取消请求
- 列表查询时,多次点击查询(每次查询条件不一样),最后一次查询很快,最终结果会被之前查询结果覆盖掉
解决方案:Axios 的 cancel token API
上面2种情况都是使用axios的cancel token API解决的,不过写法略有不同
组件销毁,取消请求
简单例子
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
// 取消请求
cancel()
vue使用mixin取消请求
// cancelTokenMixin.js
import axios from 'axios';
const CancelToken = axios.CancelToken;
const cancelTokenMixin = {
data () {
return {
cancelToken: null, // cancelToken实例
cancel: null // cancel方法
};
},
created () {
// 初始化生成cancelToken实例,注册cancel方法
this.cancelToken = new CancelToken(c => {
this.cancel = c;
});
},
beforeDestroy () {
// 组件销毁阶段调用cancel方法取消请求
this.cancel(`${this.pageName}取消请求`);
}
};
export default cancelTokenMixin;
// DataManage.vue
import cancelTokenMixin from '../mixin/cancelTokenMixin'
export default {
name: 'DataManage',
mixins: [cancelTokenMixin], // 引入mixin
data () {
....
},
mounted () {
this.getData()
},
method: {
getData () {
this.loading = true
// 请求携带cancelToken参数
axios.get('http://localhost:7000/data', { cancelToken: this.cancelToken }).then(res => {
const data = res.data
if (data.success) {
this.allData = data.fruits
this.changePage()
}
}).catch(err => {
const message = err.message || '获取数据失败';
console.log(message);
this.$message({
type: 'error',
message
})
}).finally(() => {
this.loading = false
})
},
....
}
详细说明请参考原文链接:juejin.cn/post/684490…
多次点击查询,取消请求
import axios from 'axios'
const CancelToken = axios.CancelToken
data(){
cancel:null
},
// 多次触发getList请求 取消上次请求,触发最新请求
async getList() {
if(cancel != null) {
cancel()
}
let res = await axios.post('/user/list', {
name: xxx
}, {
cancelToken: new CancelToken(c => {
cancel = c
})
})
cancel = null
}
这里就不写mixin做法了,参考上面,抽离相关逻辑即可