常见要求
- 保证请求结果的顺序OR不需要保证请求结果的顺序 ×保证执行的顺序(串行才可以实现) √保证请求结果的顺序
- 发送多个请求,不管成功还是失败OR全都成功.没有回调函数
- 需要另外的函数触发,才执行.触发之后有新请求来了,要继续执行的 OR 没有触发
- 得到请求结果(不管成功还是失败)执行回调函数OR全都成功执行回调函数
代码(不保证顺序,不管成功/失败,不需要另外函数触发,请求结束后不管成功/失败执行回调)
//tasks 存储并发请求的数组,tasks[i]执行后,发送一个并发请求
//pool 最大并发数
//cb 需要执行的回调函数
function createRequest(tasks,pool,cb){
//第一步:参数校验 三个都必须有 此处省略
//TaskQueue管理请求
class TaskQueue{
constructor(pool,cb){
this.running=0; //执行中请求个数
this.queue=[]; //存储需要执行的请求
this.results=[]; //结果,成功/失败
this.pool=pool; //并发数
}
pushTask(task){
this.queue.push(task); //全都存储在queue里面
//执行next(),能不能真的执行,看next()里面判断.反正已经存到queue里面了
this.next();
}
next(){
//this.running<this.pool 不能取"="
//queue.length 任务队列里面还有任务
//只有小于并发数并且队列里面有任务才会执行
while(this.running<this.pool && queue.length){
this.running++;
let task=this.queue.shift();
task().then(res=>{
this.result.push(res);
}).finally(()=>{
//不管成功还是失败,正在执行并发数-1,执行下一个任务
this.running--;
this.next();
})
}
//都执行完了,执行回调函数
if(this.running==0) cb(this.results);
}
}
let TQ=new TaskQueue(pool,cb);
tasks.forEach(task=>TQ.pushTask(task));
//需要追加请求,调用TQ.pushTask()即可
return TQ;
}
改进
保证顺序
新增index,保存执行的顺序
function createRequest(tasks,pool,cb){
class TaskQueue{
constructor(){
this.running=0;
this.queue=[];
this.results=[];
this.pool=pool;
this.index=0; //新增
}
pushTask(task){
this.queue.push(task);
this.next();
}
next(){
while(this.running<this.pool &&queue.length){
this.running++;
let cur=this.index; //新增
let task=this.queue[this.index++]; //取的时候的记录一下顺序
task().then(res=>{
this.result[cur]=res; //加到对于的结果里面
})
.finally(()=>{
this.running--;
self.next();
})
}
if(this.running==0) cb(this.results);
}
}
let TQ=new TaskQueue;
tasks.forEach(task=>TQ.pushTask(task))
}
需要另外的函数触发
function createRequest(tasks,pool,cb){
let go=false;
class TaskQueue{
constructor(){
this.running=0;
this.queue=[];
this.results=[];
this.pool=pool;
}
pushTask(task){
this.queue.push(task);
this.next();
}
next(){
if(!go) return;
while(this.running<this.pool &&queue.length){
this.running++;
let this.queue.shift();
task().then(res=>{
this.result.push(res);
})
.finally(()=>{
this.running--;
self.next();
})
}
if(this.running==0) cb(this.results);
}
}
let TQ=new TaskQueue;
tasks.forEach(task=>TQ.pushTask(task));
//外部函数需要调用trigger才能触发
createRequest.trigger=function(){
go=true;
}
}