zoukankan      html  css  js  c++  java
  • 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里面的实例。

    [完]

  • 相关阅读:
    java中Array/List/Map/Object与Json互相转换详解
    推荐几款开源的js日期控件
    12款优秀的 JavaScript 日历和时间选择控件
    12款优秀的 JavaScript 日历和时间选择控件
    StringTokenizer(字符串分隔解析类型)
    StringTokenizer(字符串分隔解析类型)
    javascript中的undefined 和 not defined
    javascript中的undefined 和 not defined
    6.静态函数库设计
    5. Linux应用程序地址布局
  • 原文地址:https://www.cnblogs.com/chuchur/p/10462210.html
Copyright © 2011-2022 走看看