项目中如何使用axios过滤多次重复请求详解

当我们在使用axios发起多次请求时,若存在多个相同的请求,会导致冗余的网络请求,浪费带宽和服务器资源,因此,我们需要一种方法来过滤重复的请求。下面是在项目中如何使用axios过滤多次重复请求的完整攻略。

核心思路

使用axios-middleware拦截所有的请求,将每次请求的url和method做一个唯一标识,然后将这个唯一标识作为缓存中的key,将请求的promise对象存储在以该key为键的缓存中。每次请求前首先根据这个唯一标识判断缓存中是否有相同的请求,如果存在则返回缓存中的promise对象,否则执行正常的axios请求。最后将请求成功的数据传递给下一级拦截器。

详细步骤

  1. 安装axios和axios-middleware
npm install axios axios-middleware --save
  1. 在项目中引入axios和axios-middleware,并添加全局拦截器
import axios from 'axios';
import axiosMiddleware from 'axios-middleware';

axiosMiddleware(axios, {
  interceptors: {
    request: [{
        success: function ({ getState, dispatch, getSourceAction }, config) {
          // 计算请求的唯一标识,将url和method做一个唯一字符串
          const reqKey = `${config.url}_${config.method}`;

          // 判断该请求是否已经缓存了,如果已缓存则直接返回缓存中的promise对象
          if (cache[reqKey]) {
            console.log('cached', reqKey);

            return cache[reqKey];
          }

          // 否则创建一个新的promise,将该promise存储到缓存中,并返回新的promise
          const promise = new Promise((resolve, reject) => {
            axios.request(config)
              .then(res => resolve(res))
              .catch(err => reject(err));
          });
          cache[reqKey] = promise;
          console.log('cache', reqKey);

          return promise;
        },
        error: function ({ getState, dispatch, getSourceAction }, error) {
          return Promise.reject(error);
        }
      }],
    response: [{
        success: function ({ getState, dispatch, getSourceAction }, response) {
          return response;
        },
        error: function ({ getState, dispatch, getSourceAction }, error) {
          return Promise.reject(error);
        }
      }]
  }
})
  1. 在项目中使用带缓存的axios
// 此处是一个获取用户信息的请求,带上了userid作为参数
axios.get(`/api/userinfo/${userid}`).then(data => {
  console.log(data);
});

// 再次发起相同的请求,可以发现这次请求是从缓存中取得的数据
axios.get(`/api/userinfo/${userid}`).then(data => {
  console.log(data);
});

示例说明

下面通过两个简单的例子来演示如何使用axios过滤多次重复请求。

示例一

场景:在页面中有两个按钮,每个按钮点击后都会发起一个相同的网络请求。

// html
<button id="button1">Button1</button>
<button id="button2">Button2</button>

// js
const btn1 = document.querySelector('#button1');
const btn2 = document.querySelector('#button2');

btn1.addEventListener('click', () => {
  axios.get('/api/data').then(res => {
    // 处理数据...
  }).catch(err => {
    console.log(err);
  });
})

btn2.addEventListener('click', () => {
  axios.get('/api/data').then(res => {
    // 处理数据...
  }).catch(err => {
    console.log(err);
  });
})

由于两个按钮点击后都要请求相同的数据,因此会出现重复请求数据的问题。下面使用axios-middleware来解决这个问题。

import axios from 'axios';
import axiosMiddleware from 'axios-middleware';

axiosMiddleware(axios, {
  interceptors: {
    request: [{
        success: function ({ getState, dispatch, getSourceAction }, config) {
          // 计算请求的唯一标识,将url和method做一个唯一字符串
          const reqKey = `${config.url}_${config.method}`;

          // 判断该请求是否已经缓存了,如果已缓存则直接返回缓存中的promise对象
          if (cache[reqKey]) {
            console.log('cached', reqKey);

            return cache[reqKey];
          }

          // 否则创建一个新的promise,将该promise存储到缓存中,并返回新的promise
          const promise = new Promise((resolve, reject) => {
            axios.request(config)
              .then(res => resolve(res))
              .catch(err => reject(err));
          });
          cache[reqKey] = promise;
          console.log('cache', reqKey);

          return promise;
        },
        error: function ({ getState, dispatch, getSourceAction }, error) {
          return Promise.reject(error);
        }
      }],
    response: [{
        success: function ({ getState, dispatch, getSourceAction }, response) {
          return response;
        },
        error: function ({ getState, dispatch, getSourceAction }, error) {
          return Promise.reject(error);
        }
      }]
  }
})

const btn1 = document.querySelector('#button1');
const btn2 = document.querySelector('#button2');

btn1.addEventListener('click', () => {
  axios.get('/api/data').then(res => {
    // 处理数据...
  }).catch(err => {
    console.log(err);
  });
})

btn2.addEventListener('click', () => {
  axios.get('/api/data').then(res => {
    // 处理数据...
  }).catch(err => {
    console.log(err);
  });
})

示例二

场景:在table组件中,每个单元格都需要渲染相同的数据,因此会发起重复网络请求。

// html
<table>
  <tr>
    <td><div id="cell1"></div></td>
    <td><div id="cell2"></div></td>
    <td><div id="cell3"></div></td>
  </tr>
  <tr>
    <td><div id="cell4"></div></td>
    <td><div id="cell5"></div></td>
    <td><div id="cell6"></div></td>
  </tr>
  <tr>
    <td><div id="cell7"></div></td>
    <td><div id="cell8"></div></td>
    <td><div id="cell9"></div></td>
  </tr>
</table>

// js
axios.get('/api/data').then(res => {
  document.querySelector('#cell1').innerHTML = res.data;
  document.querySelector('#cell2').innerHTML = res.data;
  document.querySelector('#cell3').innerHTML = res.data;
  document.querySelector('#cell4').innerHTML = res.data;
  document.querySelector('#cell5').innerHTML = res.data;
  document.querySelector('#cell6').innerHTML = res.data;
  document.querySelector('#cell7').innerHTML = res.data;
  document.querySelector('#cell8').innerHTML = res.data;
  document.querySelector('#cell9').innerHTML = res.data;
}).catch(err => {
  console.log(err);
});

由于在渲染table中的每个单元格时都发起了相同的网络请求,因此会出现重复请求数据的问题。下面使用axios-middleware来解决这个问题。

import axios from 'axios';
import axiosMiddleware from 'axios-middleware';

axiosMiddleware(axios, {
  interceptors: {
    request: [{
        success: function ({ getState, dispatch, getSourceAction }, config) {
          // 计算请求的唯一标识,将url和method做一个唯一字符串
          const reqKey = `${config.url}_${config.method}`;

          // 判断该请求是否已经缓存了,如果已缓存则直接返回缓存中的promise对象
          if (cache[reqKey]) {
            console.log('cached', reqKey);

            return cache[reqKey];
          }

          // 否则创建一个新的promise,将该promise存储到缓存中,并返回新的promise
          const promise = new Promise((resolve, reject) => {
            axios.request(config)
              .then(res => resolve(res))
              .catch(err => reject(err));
          });
          cache[reqKey] = promise;
          console.log('cache', reqKey);

          return promise;
        },
        error: function ({ getState, dispatch, getSourceAction }, error) {
          return Promise.reject(error);
        }
      }],
    response: [{
        success: function ({ getState, dispatch, getSourceAction }, response) {
          return response;
        },
        error: function ({ getState, dispatch, getSourceAction }, error) {
          return Promise.reject(error);
        }
      }]
  }
})

axios.get('/api/data').then(res => {
  document.querySelector('#cell1').innerHTML = res.data;
  document.querySelector('#cell2').innerHTML = res.data;
  document.querySelector('#cell3').innerHTML = res.data;
  document.querySelector('#cell4').innerHTML = res.data;
  document.querySelector('#cell5').innerHTML = res.data;
  document.querySelector('#cell6').innerHTML = res.data;
  document.querySelector('#cell7').innerHTML = res.data;
  document.querySelector('#cell8').innerHTML = res.data;
  document.querySelector('#cell9').innerHTML = res.data;
}).catch(err => {
  console.log(err);
});

通过以上两个例子可以证明,使用axios-middleware可以有效地过滤重复的网络请求,减少浪费的带宽和服务器资源。当多个页面或组件中需要渲染相同数据时,使用axios-middleware来处理网络请求非常方便。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:项目中如何使用axios过滤多次重复请求详解 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • Bootstrap3 datetimepicker控件使用实例

    Bootstrap3 datetimepicker控件使用实例 介绍 datetimepicker控件是基于Bootstrap3的开源jQuery插件,用于日期和时间选择。它具有用户友好的界面,易于使用和高度可定制的特点。本文将详细介绍datetimepicker控件的使用方法和示例。 安装 要使用datetimepicker控件,首先需要引入相关的库文件:…

    Vue 2023年5月28日
    00
  • vue中为什么在组件内部data是一个函数而不是一个对象

    在Vue中,组件内部的data需要一个函数来返回一个对象,而不能直接使用一个对象。这是因为组件在Vue的框架下是一个被复用的实例,如果直接使用一个对象作为组件的data属性,那么复用的组件实例将会共享同一个data,从而导致数据污染。 举个例子,假设我们有一个组件A和一个组件B,它们都使用了同一份data对象。当我们使用组件A时,修改data对象的某个属性值…

    Vue 2023年5月28日
    00
  • 使用 Vue 绑定单个或多个 Class 名的实例代码

    下面是详细讲解使用Vue绑定单个或多个Class名的实例代码的完整攻略: Vue绑定单个Class名 示例说明: 在模板中使用v-bind或简写形式:来绑定class,需要将要绑定的class名作为一个JavaScript表达式。 方式一:对象语法 绑定单个class名的方式一:对象语法 <template> <div :class=&qu…

    Vue 2023年5月28日
    00
  • Vue的列表之渲染,排序,过滤详解

    Vue的列表之渲染,排序,过滤详解 在Vue中,渲染、排序、过滤列表是非常常见的需求。Vue提供了强大的指令和方法来实现这些需求,下面将分别进行详细介绍。 列表渲染 Vue中通过v-for指令可以很容易地渲染数组或对象列表。下面是一个v-for指令的示例: <ul> <li v-for="item in items"&g…

    Vue 2023年5月28日
    00
  • nuxt.js 在middleware(中间件)中实现路由鉴权操作

    要在Nuxt.js中实现路由鉴权操作,可以通过中间件来实现。具体步骤如下: 1. 创建中间件 在Nuxt.js项目中创建一个中间件来实现路由鉴权操作,可以在/middleware目录下创建一个auth.js文件。代码如下: export default function({ route, redirect, store }) { // 获取当前路由信息 co…

    Vue 2023年5月27日
    00
  • Vue中的vue-resource示例详解

    Vue中的vue-resource示例详解 什么是vue-resource vue-resource是一个Vue.js插件,用于通过XHR实用RESTful API。 安装和引用 安装: npm install vue-resource –save 引用: import VueResource from ‘vue-resource’ Vue.use(Vue…

    Vue 2023年5月28日
    00
  • 详解django模板与vue.js冲突问题

    我将为你讲解 “详解django模板与vue.js冲突问题”的完整攻略。 在前端开发过程中,我们常常使用前端框架来实现快速的开发,而Vue.js是一款非常流行的前端框架,许多项目中都会使用到它,但是在使用Vue.js的同时又要使用Django模板渲染时,就容易发生冲突问题。 1. Vue.js与Django模板的冲突原因 在Vue.js中,它使用“双花括号”…

    Vue 2023年5月28日
    00
  • vue中的el-form表单rule校验问题(特殊字符、中文、数字等)

    我来详细讲解一下Vue中的el-form表单rule校验问题。 1. 概述 在Vue的el-form表单中,通过设置rules属性可以对表单进行校验,并在提交时提示错误信息。但是在实际开发中,我们可能会遇到特殊字符、中文、数字等问题,这时我们就需要对规则进行特殊处理。 2. 校验规则详解 在Vue的el-form表单中,校验规则可以通过rules属性进行设置…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部