最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 如何实现防止重复的网络请求

    正文概述 掘金(Daes)   2021-01-26   680

    前言

    实现思路

    如何实现防止重复的网络请求

    1.平时我们写接口是这样的:

    请求接口文件

    import { http } from '@/plugin/axios'; // 导入请求接口 http
    
    // 初始化
    export function getInit(params) {
        return http({
            method: 'get',
            url: '/xxx/xxx/xx',
            params,
        });
    }
    

    主要就是这里执行 httpRequest方法的时候做操作;

    执行httpRequest函数的时候能获取到请求所有配置 config

    2.这里演示使用axios,执行请求函数的时候外面包一层

    axios.js配置文件

    import axios from 'axios';
    import { httpRequest } from './options'; // 这里就是我们要实现的逻辑文件
    
    // 里面做一些请求拦截,响应拦截操作 具体查看axios文档
    const service = axios.create({
        baseURL: 'xxx/xxx',
    });
    
    // 请求拦截器
    service.interceptors.request.use(config => {}, error => {})
    
    // 响应拦截器
    service.interceptors.response.use(response => {
      completeRequest(response); // 2.响应请求回来执行
    }, error => {
      
    })
    
    export function http(config) { // => 这里config就是传递的请求配置参数
        return httpRequest(config, service); // +
    }
    
    

    3.防止重复网络配置文件

    options.js

    (1)发送请求前,查看请求队列里是否有当前请求(url地址来判断)

    • 请求队列有当前url地址, 取消请求 返回promise.reject失败
    • 没有当前请求,正常发送请求
    /**
     * 职责: 防止重复的网络请求
     *
     */
    
    const list = []; // 1.请求队列
    
    // 合并 方法 参数 url地址
    function getUrl(config = {}) {
      // get请求 params参数 post请求 data参数, baseURL
      const { url, method, params, data, baseURL = '' } = config;
      const urlVal = url.replace(baseURL, '');
      return `${urlVal}?${method === 'get' ? getformatObjVal(params) : getformatObjVal(data)}`;
    }
    
    // 处理 url地址 
    const getformatObjVal = (obj) => {
      obj = typeof obj === 'string' ? JSON.parse(`${obj}`) : obj;
      var str = [];
      for (let p in obj) {
        if (obj.hasOwnProperty(p) && p !== '_t') {
          var item = obj[p] === null ? '' : obj[p]; // 处理null
          str.push(encodeURIComponent(p) + '=' + encodeURIComponent(item));
        }
      }
      return str.join('&');
    }
    
    // 2.请求方法
    export function httpRequest(config = {}, axios) {
      const url = getUrl(config); //3. 这里我们获取到了URL地址
    
      if (list.includes(url)) {  // 4.查看请求队列是否有当前url地址
        return Promise.reject('In the request'); // 5.在请求队列里面 取消当前请求, 返回Promise失败结果
      }
    
      // 6. 请求队列没有当前url地址 发送请求, 返回Promise成功
      return Promise.resolve(axios); 
    }
    

    (2)请求响应回来后,在请求队列里删除当前url地址; (下一次请求就可以正常发送)

    options.js

    // 请求响应回来执行这个函数
    export function completeRequest(response = {}) {
      const { config } = response; // 1.response里面config能拿到配置参数
      const url = getUrl(config); // 2.获取url地址 
      const index = list.indexOf(url); // 3. 查找在队列的索引
      if (index > -1) {
        list.splice(index, 1); // 4.删除请求队列中的当前请求url地址
      }
    }
    

    axios.js

    import axios from 'axios';
    import { httpRequest, completeRequest } from './options'; // 防止重复请求
    
    const service = axios.create({
        baseURL: 'xxx/xxx',
    });
    
    // 请求拦截器
    service.interceptors.request.use(config => {}, error => {})
    
    // 响应拦截器
    service.interceptors.response.use(response => {
      completeRequest(response); // 2.响应请求回来执行  +
    }, error => {
      
    })
    
    
    // 导出请求
    export function http(config) {
        return httpRequest(config, service);  // 1.发送请求前执行
    }
    
    

    到这里已经实现了防止重复的网络请求,但还有一个问题,响应请求发生异常了要清除请求队列中当前url地址。不清理,下一次发送请求直接被取消掉 (这里我就随便写了一个方法,把请求队列全部清空,大家可以按自己场景来写)。

    /**
     * 清空所有请求队列
     */
    export function clearRequestList() {
      list = []; // 这里我就直接清空了
    }
    

    完整http.js文件

    import axios from 'axios';
    import { httpRequest, completeRequest, clearRequestList } from './options'; // 防止重复请求 +
    
    const service = axios.create({
        baseURL: 'xxx/xxx',
    });
    
    // 请求拦截器
    service.interceptors.request.use(config => {}, error => {})
    
    // 响应拦截器
    service.interceptors.response.use(response => {
      completeRequest(response); // 2.响应请求回来执行
    }, error => {
      clearRequestList(); // + 
    })
    
    
    // 导出请求
    export function http(config) {
        return httpRequest(config, service);  // 1.发送请求前执行
    }
    

    完整options.js

    /**
     * 职责: 防止重复的网络请求
     *
     */
    
    const list = []; // 1.请求队列
    
    // 合并 方法 参数 url地址
    function getUrl(config = {}) {
      // get请求 params参数 post请求 data参数, baseURL
      const { url, method, params, data, baseURL = '' } = config;
      const urlVal = url.replace(baseURL, '');
      return `${urlVal}?${method === 'get' ? getformatObjVal(params) : getformatObjVal(data)}`;
    }
    
    // 处理 url地址 
    const getformatObjVal = (obj) => {
      obj = typeof obj === 'string' ? JSON.parse(`${obj}`) : obj;
      var str = [];
      for (let p in obj) {
        if (obj.hasOwnProperty(p) && p !== '_t') {
          var item = obj[p] === null ? '' : obj[p]; // 处理null
          str.push(encodeURIComponent(p) + '=' + encodeURIComponent(item));
        }
      }
      return str.join('&');
    }
    
    // 2.请求方法
    export function httpRequest(config = {}, axios) {
      const url = getUrl(config); //3. 这里我们获取到了URL地址
    
      if (list.includes(url)) {  // 4.查看请求队列是否有当前url地址
        return Promise.reject('In the request'); // 5.在请求队列里面 取消当前请求, 返回Promise失败结果
      }
    
      // 6. 请求队列没有当前url地址 发送请求, 返回Promise成功
      return Promise.resolve(axios);
    }
    
    
    /**
     * 请求响应回来执行这个函数
     */
    export function completeRequest(response = {}) {
      const { config } = response; // 1.response里面config能拿到配置参数
      const url = getUrl(config); // 2.获取url地址 
      const index = list.indexOf(url); // 3. 查找在队列的索引
      if (index > -1) {
        list.splice(index, 1); // 4.删除请求队列中的当前请求url地址
      }
    }
    
    /**
     * 清空所有请求队列
     */
    export function clearRequestList() {
      list = []; // 这里我就直接清空了
    }
    
    

    以上就是我实现防止网络请求的方式,之前我有使用过axios中CancelToken来进行取消请求;当会有一些问题。

    1. 需要配置请求文件,不友好,团队开发配置也比较麻烦。
    2. 需要给每个请求都配置CancelToken。 有两个方法使用它 具体可以参考官网文档

    下载网 » 如何实现防止重复的网络请求

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元