题目来源
今天看到公众号推送了一篇关于用JS实现请求的串行和并行的文章,然想自己试一下。
题目
假设现在有这么一种场景:现有 30 个异步请求需要发送,但由于某些原因,我们必须将同一时刻并发请求数量控制在 5 个以内,同时还要尽可能快速的拿到响应结果。
- 请求的串行:按照规定的次序依次完成请求,一般用于带有依赖关系的请求
-
请求的并行:同时执行多个异步请求,对请求先后完成的顺序没有要求
我们平时都是基于promise来封装异步请求的,这里也主要是针对异步请求来展开。
串行的实现
假设我们的请求处在一个理想化的状态下,每次都可以在规定的时间内成功返回。
- 实现一个请求类,属性包括请求名,和请求所需要的时间,以及发送请求的方法(使用promise)
//请求类
class Request{
//连个属性
constructor(name,delay) {
this.name = name;
this.delay =delay
}
//发送请求的方法
sendRequest(){
let time = this.delay
return new Promise(function (resolve, reject) {
setTimeout(()=>resolve('status: ok '+' | runtime:'+time+'ms'),time)
})
}
}
//new两个请求实例
let test1 = new Request('userinfo',1000)
let test2 = new Request('productinfo',2000)
//请求的串行
test1.sendRequest().then(function (result) {
console.log(result)
test2.sendRequest().then(function (result) {
console.log(result)
})
})
//请求的串行(then中使用箭头函数简化代码)
test1.sendRequest().then((result) => {
console.log(result)
test2.sendRequest().then(result=>console.log(result))
})
并行请求的实现
let test1 = new Request('userinfo', 1000)
let test2 = new Request('productinfo', 2000)
let test3 = new Request('productinfo', 5000)
let container = [test1.sendRequest(),test2.sendRequest(),test3.sendRequest()]
Promise.all(container).then(
result=> {
console.log(result)
}
// console.log('end')
)
并行请求的数量限制
假如请求容器中一次产生上万条请求需要并行处理,如果同时发送请求的话有可能造成内存溢出,所以需要对请求容器进行分段处理,每次并行处理指定数量的请求,用来减少资源的消耗
- 首先我们需要一个函数处理并发请求,这个函数要处理一个装着许多,非依赖请求的数组,以及可以同时处理多少个请求数量的参数。
- 因为每次批量处理请求的数量有限制,所以我们还需要一个方法将传入的数组处理成长度较小的数组
- 既然每个请求都返回一个promise,所以我们用promise.all对较小数组中的请求进行一次包装,使用promise.all对请求进行处理可以使所有请求都达到resolve状态后再执行回调。
function senAll(urls=[],maxNum) {
//如果全部请求数小于允许的最大值,直接发送全部请求
if (urls.length<maxNum){
return sendRequest(urls)
}
//对请容器进行定长裁剪处理,并进行请求完成数量的检测
else {
return 0
}
// 请求的批量处理
function sendRequest(requests=[]){
//如果不在数组中调用请求则在调用实例的请求方法
return Promise.all(requests).then(
result=>{
console.log(result)
}
)
}
}
网友评论