应用场景
取消请求偶尔会用到,以下是两个工作中可能用到的场景
- 如果一个数据请求量比较大(可能会请求错误),还没请求完就切换路由,可能会出现错误的提示框(响应拦截器中配置错误提示)
- 导出文件或下载文件时,中途取消
- 一个请求请求量比较大,发送新请求时需要取消上一个请求
取消单个请求(结合生命周期使用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import axios from 'axios' import { generatePlan } from '@/api'
export default { data() { return { $cancel: null } }, destroyed() { this.cancelPost() }, methods: { generateList() { const self = this this.$confirm('生成时间比较长,您是否确定生成?', '警告', { confirmButtonText: '确定', cancaelButtonText: '取消', }) .then(() => { this.cancelPost() return generatePlan({ params: this.listQuery, cancelToken: new axios.CancelToken(function exector(c) { self.$cancel = c }), }).then(res => { if (res.code === 200) this.list = res.data.result }) }) .catch(() => {}) .finally(() => { self.$cancel = null }) }, }, cancelPost() { typeof this.$cancel === 'function' ? this.$cancel('取消请求') : null }, }
|
取消所有请求(结合导航守卫)
思路:在请求拦截器中,给所有请求加一个 token,设置全局变量 source 控制 cancel token,在路由变化时调用 cancel 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| http.interceptors.request.use( config => { config.cancelToken = store.source.token return config }, error => { return Promise.reject(error) } )
router.beforeEach((to, from, next) => { const CancelToken = axios.CancelToken store.source.cancel && store.source.cancel() store.source = CancelToken.source() next() })
|
axios 取消请求原理
axios 是对 XMLHttpRequest 的封装,使用 XMLHttpRequest 实例的 abort()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| if (config.cancelToken) { config.cancelToken.promise.then(function onCanceled(cancel) { if (!request) { return }
request.abort() reject(cancel) request = null }) }
|