防止重复发ajax请求是平时开发中遇到频次较高的问题了。我通常解决方案有如下几种,
1. UI限制。
点击完按钮后,就禁用按钮, 并开启显示等待动画,收到服务器的成功响应后,再隐藏动画,最好设置超时,时间不要太长,如果太长,用户会骂街。
(网络图片, 侵删)
2. JS封锁。
(1)如果用户属于暴力连续点击按钮,可以通过函数防抖来做,其实就是闭包里的setTimeout 与clearTimeout, 连续的点击会把上一次点击处理函数清掉,我们的 ajax请求会在最后一次点击后再发出。
(2)多个tab 快速切换,如果从tab1快速切换到tab2,再从tab2快速切换到tab1,不避免的同一个tab 要重复发起多次请求。
除了多次请求的问题,还有一个问题就是,如果在单页面应用中,切换tab后dom 销毁了,此时数据回来了,如果去操作了已经销毁的dom,那么控制台会报错。而在vue ,react 等不需要开发者去操作的dom的框架,我们去修改状态,也会报出如下的警告信息,
解决这个问题的思路就是abort掉上一个请求。XMLHttpRequest对象有abort方法,可以直接调用。
如果使用第三方的请求库的话,比如axios,我们可以为我们的请求创建一个cancel token ,在每个请求设置一个token,在页面切换, 或者组件销毁前,只需要通过source.cancel取消就好了,其实原理还是通过xhr的abort方法实现。
具体的代码以及流程可以参考如下。
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// handle error
}
});
// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');
当然最终解决这个问题还是要根据场景,灵活选择,要有自己的freestyle.
来源:千锋HTML5