前端开发过程中发送网络请求时,没等接收到请求时,用户再次触发发送请求时间,就会造成高并发。
再比如做页面滚动加载更多时,页面滑动到底部时,会多次触发请求事件。
这里我将使用高阶函数在不修改之前的请求方法和触发事件等情况下,来优雅的解决。
以下是模拟触发事件和网络请求的代码。每点击一次按钮后,都会触发一次request方法。
// html 代码
<button id="btn"></button>
// js 代码
// 绑定点击事件
document.getElementById("btn").onclick = function(){
request(Date.now());
};
// 请求函数
function request(time){
console.log("正在发送请求");
return new Promise((resolve)=>{
setTimeout(()=>{
console.log("成功获取返回数据")
resolve({code: 0, result: time});
}, 3000);
})
}
下面,创建一个新的函数命名为wrappedRequest, 它接收一个函数,判断这个函数是否被执行了,如果执行了则不会再执行此函数。若没有执行,则继续执行次函数。
// 包裹请求函数
function wrappedRequest(func){
// 给func添加一个isRequest属性,用来标记是否发送请求了,如果为true,则不再进行发送请求
if(func.isRequest){
// 这里返回一个空的promise函数,否则会报错
return () => new Promise(()=>{});
}
// 没有发送请求时,这里需要发送请求,并且将isRequest标记为true
func.isRequest = true;
return function(){
func.apply(this, arguments).then(resp => {
// 接收到请求后,将isRequest标记为false
func.isRequest = false;
// 返回请求结果
return resp;
})
}
}
// 绑定点击事件
document.getElementById("btn").onclick = function(){
// 在这里不过点击了多少次,只会请求一次,直到返回结果。
wrappedRequest(request)(Date.now());
};