最近碰到一个很头疼的问题,一个下拉多选框多选,每选一个触发接口筛选一次数据,这个不是关键关键是数据的更新影响视图里面表格的表头的渲染,然后操作一快导致页面就炸了,场面十分鬼畜。产生这个问题的原因在于,当你在不断发起请求的时候,可能会出先这样一个情况,先发起的请求还处在pending状态,后面的请求已经有了结果,过了一段时间之前的的请求又有了响应导致原本我在选择条件一的时候筛选数据没有反应于是我又选了条件二显示了条件二的结果这个时候突然又有了条件一的返回,页面渲染就开始不正常了,再点击结果只会更加鬼畜。
后来终于找到解决方案就是利用axios终止多次请求,解决的思路就在于,当你在不断发起异步请求的时候,如果说后面的请求有了响应前面的还在pending我就终止之前的请求,这样就很好的解决了这个问题。思路有了,具体如何实现的代码
<template> <input type="text" v-model="val"> <template> <script> import axios from "axios"; export default { name: 'hello', data() { return{ val: '', canMsg: '请求终止', }, methods: { cancelReq() { if (typeof this.source === 'function') { this.source(canMsg); } } }, watch: { val(newVal) { var that = this; this.cancelReq(); //取消请求 axios.get('xxx', { cancelToken: new axios.CancelToken(function(c) { that.source = c; }) }).then((res) => { ... }).catch((err) => { if (axios.isCancel(err)) { // 返回取消请求信息 console.log('Rquest canceled', err.message); } else { console.log(err); } }) } } } </script>
实际项目中的引用:
https://www.jb51.net/article/149222.html
问题是解决了,axios终止了请求,但是axios又是怎么终止请求的呢?如果你是新手小白到这问题解决了那你可以走了,如果你是几年的开发知道其背后的源码实现原理我想还是有必要的。
简单版完整代码
// 创建Promise,返回放行开关cancel function source () { var cancel; var promise = new Promise(function (resolve) { cancel = resolve; }); return { cancel:cancel, token:promise } } // 发请求 function axios_get(config) { if (config.cancelToken) { config.cancelToken.then(function () { xhr.abort(); }) } } // 代码执行 var source = source(); axios_get({cancelToken:source.token}); setTimeout(function () { source.cancel(); // 5秒之后执行下一步操作 },5000)
我们在发送请求的时候将cancelToken作为配置项传入,注意值为source.token 他是source方法里面rerurn出来的一个promise对象把resolve赋值给cancel,然后在发请求里面通过.then来请求xhr.abort()方法
这个方法的作用是:
如果该请求已被发出,XMLHttpRequest.abot() 方法将终止该请求。当一个请求被终止,它的 readyState
将被置为 XMLHttpRequest.UNSENT
(0),并且请求的 status
置为 0。
最后在调用source.cancel来取消请求。
这个过程理解十分苦涩需要反复研读。
参考链接:https://www.cnblogs.com/qidaoxueyuan/p/12396955.html
项目里面应用:
需要中断的接口这样配置:
// 学分查询 export function GetCredit(params,_this) { const CancelToken = axios.CancelToken; return fetch({ url: '/api/netcore/smartcredit/v1/Statistics/GetStudentXmReport', method: 'post', data: params, cancelToken: new CancelToken(function executor(c) { _this.cancelAjax = c }) }); }