前端开发经常会调用各种后端接口,这些操作都是异步的,有的接口还有并发限制,这时候就需要对接口调用进行管理,限制同时请求的接口数量,对于这种情况,一般都使用队列来解决并发问题。其难点在于异步流程的设计。
举一个简单的例子:我们想了解某个网站提供的一系列数据,从这些数据做辅助分析,所以需要获取大量数据,但是这个网站做了并发限制,同一时间内最多有3次请求,如果超了,就会返回错误,如果我们不处理并发,后面就会一直得到报错。
实现的思路如下:
1.把要发起的所有请求都放到一个数据池
2.从数据池里拿出一个请求,请求完成再拿出一个,如此往复。
我们可以使用数组来存放请求任务,并递归函数来实现取数据操作,还可以使用promise来简化流程。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| class Task { constructor(resolve, fn, args) { this.resolve = resolve this.fn = fn this.args = args } }
class Queue { constructor(concurrent) { this.concurrent = concurrent this.count = 0 this.queue = [] } addTask(fn, args) { return new Promise((resolve,reject)=>{ this.queue.push(new Task(resolve,fn,args)) if (this.count < this.concurrent) { this.pullTask() } } ) }
pullTask() { if (!this.queue.length) { return } const {resolve, fn, args} = this.queue.shift() resolve(this.runTask(fn, args)) }
runTask(fn, args) { this.count++ const result = Promise.resolve(fn(args)) result.finally(()=>{ this.count-- this.pullTask() } ) return result } }
|