当我们在使用axios发起多次请求时,若存在多个相同的请求,会导致冗余的网络请求,浪费带宽和服务器资源,因此,我们需要一种方法来过滤重复的请求。下面是在项目中如何使用axios过滤多次重复请求的完整攻略。
核心思路
使用axios-middleware拦截所有的请求,将每次请求的url和method做一个唯一标识,然后将这个唯一标识作为缓存中的key,将请求的promise对象存储在以该key为键的缓存中。每次请求前首先根据这个唯一标识判断缓存中是否有相同的请求,如果存在则返回缓存中的promise对象,否则执行正常的axios请求。最后将请求成功的数据传递给下一级拦截器。
详细步骤
- 安装axios和axios-middleware
npm install axios axios-middleware --save
- 在项目中引入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);
}
}]
}
})
- 在项目中使用带缓存的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技术站