现象:在项目中遇到一个问题,每进入一个页面,都要去请求数据,一般都不是一个接口,当这些接口报错时,会有提示信息,每个接口都有一个提示,这时就会出现一大堆的提示信息,很不友好~~,怎么解决呢?
原因:一进入页面的这些请求都是并发的,没有先后顺序,先完成的报错了,后面的接口依然在请求中,现在想达到的目的就是,前面的报错了,后面正在进行中的请求就取消了吧。
解决方案:
1.利用 axios.CancelToken来取消请求
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
// 请求拦截器
request.interceptors.request.use(config=>{
config.cancelToken = source.token // 写入取消请求的标识
})
// 响应拦截器
request.interceptors.response.use(
respose=>{},
error=>{
source.cancel() // 失败后调用取消请求函数
}
)
这种方法的缺点是之后再做其他操作,接口均不能正常取消了,因为用的是同一个cancel,这个cancel只能用一次 。
2.利用 new axios.CancelToken() 来取消请求
// 请求拦截器
let cancel = null
request.interceptors.request.use(config=>{
config.cancelToken = new axios.CancelToken(function(c){ cancel = c; }); // 每个请求都有一个cancel函数
})
// 响应拦截器
request.interceptors.response.use(
respose=>{},
error=>{
cancel && cancel() // 失败后调用取消请求函数
}
)
3. fetch 请求中的中断请求---AbortController对象
根据文档说明我们可以了解到,AbortController接口代表一个控制器对象,允许你在需要时中止一个或多个Web(网络)请求。
需要new AbortController实例abortController,然后使用abortController.signal生成关联变量再添加到fetch请求参数中去,最后想要中断的时候使用关联该请求的abortController.abort()方法使该请求中断
const abortController = new AbortController();
fetch(`https://xxx.com/data/${id}`, {
signal: abortController.signal,
})
.then((resp) => {
if (resp.ok) {
return resp.json();
}
return Promise.reject();
})
.then((data) => {
console.log(data);
})
.catch(() => {
if (abortController.signal.aborted) {
console.log('请求已取消');
} else {
console.error('请求失败');
}
})
// 中断请求
abortController.abort();
延伸:cancelToken还能用在输入框的监听、重复点击,重复请求中的取消请求。可以在拦截器中设置满足一定条件(url一样,参数一样,时间<200ms等)执行cancel()。
这篇文章 写的非常好,可以去看看传送门: https://juejin.cn/post/7189231050806001719