Axios多请求场景下cancelToken取消及删除逻辑的异常行为排查
问题根因分析
removeLoader方法存在变量名拼写错误:你声明了state的拷贝对象为loadersObj,但后续取消token、删除属性操作的是未定义的loaders变量,实际对loadersObj没有做任何修改,最后直接把未修改的loadersObj赋值回state.loaders,导致旧的cancelToken一直残留在state中。每次新请求触发addLoader时都会先取消上一次残留的旧token,刚好对应你观察到的奇偶次请求异常:第2次请求取消第1次、第3次请求取消第2次,若没有后续请求,第3次(奇数次)请求就会正常发送。add作为Vuex的action,调用addLoader这个mutation时没有使用commit方法,直接调用addLoader不会触发Vuex的状态更新逻辑,你后续读取的state.loaders[item.id].token大概率是过期的旧值。- 没有对Axios取消请求抛出的异常做捕获:请求被取消后会直接抛出错误,后续的状态提交、移除loader逻辑都会中断,
removeLoader根本不会执行,进一步加重了token残留的问题。
修复代码
修复add action
async add({ dispatch, commit, state }, { item }) { // 调用mutation必须用commit触发 commit('addLoader', {id:item.id}); try { let { data } = await this.$axios.get("/add", { params: item, cancelToken: state.loaders[item.id].token, }); // 正常请求完成的业务提交逻辑 // commit adding the item } catch (err) { // 仅处理非取消类的请求错误 if (!this.$axios.isCancel(err)) { console.error('请求出错', err) } } finally { // 不管请求成功、失败还是被取消,都移除对应loader清理token commit('removeLoader', {id: item.id}) } },
修复removeLoader mutation
直接启用你注释的正确逻辑即可:
removeLoader(state, { id }) { if (state.loaders[id]) { const loadersObj = { ...state.loaders }; // 先持有token引用再取消、删除,避免引用丢失导致取消失效 const loader = loadersObj[id]; loader.cancel(); delete loadersObj[id]; state.loaders = loadersObj; } else { console.log("didnt find any loader", id); } },
验证效果
修复后同id的重复请求会自动取消上一次未完成的请求,最后一次发起的请求会正常执行,不会再有奇偶次异常、token残留的问题。
内容的提问来源于stack exchange,提问作者ishaishai
相关产品推荐
相关产品推荐

