定义
当前网络请求完成时(成功、失败、或者超时),才能进行下一个网络请求,这就是网络请求队列。
使用场景
客户端短时间内产生的网络请求次数过多,造成服务器压力过大,需要限制下一个网络请求的参数依赖上一个网络请求的结果每次网络请求的参数结构和返回结果基本一样解决小程序只能同时并发5个请求的限制
网络请求队列的代码实现
let currentRequestQueue
= [];
let currentRequestResponse
= true;
let requestTimes
= 0;
let responseFailTimes
= 0;
let responseSuccessTimes
= 0;
function requestQueue(){
if(this.currentRequestQueue
.length
> 0 && this.currentRequestResponse
){
this.updateData(this.currentRequestQueue
.shift());
}
}
function updateData(params
){
requestTimes
++;
currentRequestResponse
= false;
fetch('http://127.0.0.1:8080/app/update',{
method
:'POST',
headers
:{"Content-Type": "application/json;charset=UTF-8"},
body
:JSON.stringify(params
)
}).then((response
) => response
.json())
.then( res
=>{
if(res
.header
.statusCode
== 'success'){
responseSuccessTimes
++;
}else{
currentRequestQueue
.unshift(params
);
responseFailTimes
++;
}
currentRequestResponse
= true;
requestQueue();
requestResult();
}).catch( err
=>{
currentRequestQueue
.unshift(params
);
responseFailTimes
++;
currentRequestResponse
= true;
requestQueue();
requestResult();
})
}
function requestResult(){
console
.log(`网络请求次数:${requestTimes}`,`失败:${responseFailTimes}`,`成功:${responseSuccessTimes}`);
if(responseSuccessTimes
== requestTimes
){
initAfterRequest();
console
.log('网络请求全部成功');
}else if(responseFailTimes
== requestTimes
){
initAfterRequest();
console
.log('网络请求全部失败');
}else if(responseSuccessTimes
+ responseFailTimes
== requestTimes
){
initAfterRequest();
console
.log('网络请求部分成功');
}
}
function initAfterRequest(){
requestTimes
= 0;
responseFailTimes
= 0;
responseSuccessTimes
= 0;
}
for(let i
= 0; i
< 10; i
++){
let params
= {
userId
:'abcd123456',
data
:i
}
currentRequestQueue
.push(params
);
}
requestQueue(currentRequestQueue
);
上述网络请求使用的是fetch请求,也可以更换成Ajax请求的方式。
扩展:
当网络队列请求次数过多,需要过多时间来处理时,为提升用户体验,可以设置一个按钮让用户手动停止网络请求队列
实现方法:首先定义一个变量isStopRequest ,然后在requestQueue里判断此变量即可
let isStopRequest
= false;
function requestQueue(){
if(isStopRequest
){
console
.log('手动停止网络请求队列');
return;
}
if(this.currentRequestQueue
.length
> 0 && this.currentRequestResponse
){
this.updateData(this.currentRequestQueue
.shift());
}
}
当网络状况不好时,请求失败次数超过3次时,自动停止网络请求队列
实现方法:在requestQueue里判断变量responseFailTimes即可
function requestQueue(){
if(responseFailTimes
>= 3){
console
.log('网络请求队列因网络失败次数过多自动停止');
return;
}
if(this.currentRequestQueue
.length
> 0 && this.currentRequestResponse
){
this.updateData(this.currentRequestQueue
.shift());
}
}
如果对于数据比较敏感或者对数据的完整性要求较高,当停止网络请求队列时可以将当前还未发送的网络请求队列保存在本地缓存,当用户再次触发时读取缓存并将上次未发送的请求加入到网络请求队列。
当网络意外断开时,当前的网络请求会立即返回失败的回调,并将当前网络请求队列保存到缓存中。而当前的请求其实已经成功发送到服务器上,只是客户端还没有收到请求成功返回的数据,当下次再次读取缓存并将上次未发送的请求加入到网络请求队列,就会导致比实际上多了一个请求,造成数据错误。
解决办法:
客户端:在生成网络请求的时候加入当前请求的时间戳,代码如下:
for(let i
= 0; i
< 10; i
++){
let params
= {
userId
:'abcd123456',
data
:i
,
synchronized_time
:String(new Date().getTime())
}
currentRequestQueue
.push(params
);
}
服务器端:判断当前请求的时间戳跟上次请求的时间戳是否一样,如果一样,返回请求成功,但此次请求改变的数据不更新到数据库中。