vue路由切换终止请求

Posted chuchur

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue路由切换终止请求相关的知识,希望对你有一定的参考价值。

问题:

在SPA模式开发当中,比如VUE ,当前路由切换的时候如何终止正在发生的异步请求呢,

结果:

假如请求超时并且有设定超时时间。有一堆的异步请求在执行,当用户切换到另一个页面,这些请求还未终止,并且当服务器响应之后,反馈的结果不是当前页面所期待的。最终会误导用户造成一些不必要的结果。也给web 造成性能问题。

解决方案:

把执行的请求存入队列,当路由切换的时候终止队列里的异步请求。

首先搞一棵树来存储请求队列

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let store = new Vuex.Store({
   state:{
        requests:[]
   }
})

new Vue({
  el: '#app',
  router: router,
  render: h => h(App),
  store
})

利用ajax请求和终止

var xhr = $.ajax({type:'POST',
    url:'xxxsx',
    data:'',
    success:function(){
        alert('ok');
    }
})
//xhr.abort()  终止请求
this.$store.state.requests.push(xhr)

利用superagent请求 和终止

const request = require('superagent')
var xhr = request('post','/api/xxxx/xxxx')
xhr.send(data)
//xhr.query(data) //get 传参
xhr.end((err,res)=>{
    ...todo...
})
//xhr.abort() 终止请求
this.$store.state.requests.push(xhr)

利用axios 请求

import axios from 'axios'
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/api/xxxxx/xxxxx', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

// 取消请求(message 参数是可选的)
//source.cancel('Operation canceled by the user.');

this.$store.state.requests.push(source)

利用vue-resource请求

import Vue from 'vue'
import req from 'vue-resource'
Vue.use(req)

this.$http.get('/someUrl', {    
    before(request) {
        this.$store.state.requests.push(request)
        //request.abort(); 终止请求
    }
  }).then(response => {
    // success callback
  }, response => {
    // error callback
  });

利用fetch 请求

fetch 貌似无法监控读取进度和终端请求,他没有timeout机制,没有progress提示,但是可以利用Promise 来实现终止

var _fetch = (function(fetch){
  return function(url,options){
    var abort = null;
    var abort_promise = new Promise((resolve, reject)=>{
      abort = () => {
        reject('abort.');
        console.info('abort done.');
      };
    });
    var promise = Promise.race([
      fetch(url,options),
      abort_promise
    ]);
    promise.abort = abort;
    return promise;
  };
})(fetch);

var xhr = _fetch('/api/xxx/xxxx',{methods:'POST',body:data});
xhr.then(function(res) {
    console.log('response:', res);
}, function(e) {
    console.log('error:', e);
});
xhr.abort(); //终止

this.$store.state.requests.push(xhr)

那么知道如何终止请求,然后也存储了请求实例,剩下的只要监听路由就行了

let router = new Router({....})
//每次路由改变之前终止所有的请求实例
router.beforeEach(function (to, from, next) {
    this.$store.state.requests.forEach(xhr=>xhr.abort()) //终止所有的请求实例
    this.$store.state.requests =[] //执行完清空,等待下一次的页面的请求装载
    next()
})

这种只是假设,自然请求完成之后最好,还是手动释放树的请求示例。例如ajax 请求完成之后 在complite 里面 splice store里面的实例。

[完]

以上是关于vue路由切换终止请求的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段11——vue路由的配置

VSCode自定义代码片段11——vue路由的配置

Vue路由切换&Axios接口取消重复请求

vue路由对象($route)参数简介

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装