-
Notifications
You must be signed in to change notification settings - Fork 51
/
浏览器最大请求并非限制.js
48 lines (45 loc) · 1.48 KB
/
浏览器最大请求并非限制.js
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
class RequestLimit {
constructor(limit) {
// 定义一个自己的并发请求控制类在实例化时设置 limit
this.limit = Number(limit) || 2
this.blockQueue = []
this.currentReqNumber = 0
}
/**
* 请求
* @param {*} req
*/
async request(req) {
// 为这个这个并发请求控制类实现一个 request 方法
if (!req) {
throw new Error('req is required.')
}
if (Object.prototype.toString.call(req) !== '[object Function]') {
throw new Error('Req must be a function.')
}
if (this.currentReqNumber >= this.limit) {
// 在 request 里判断如果当前请求数大于设置的 limit 程序进入阻塞状态
await new Promise((resolve) => this.blockQueue.push(resolve)) // 阻塞队列增加一个 Pending 状态的 Promise
}
return this._handlerReq(req) // 在 request 请求里如果当前请求数小于设置的 limit,处理传入的请求
}
/**
* 内部方法处理请求
* @param {*} req
*/
async _handlerReq(req) {
this.currentReqNumber++ // 在处理传入的请求开始时要对当前请求数做加 1 操作
try {
return await req()
} catch (err) {
return Promise.reject(err)
} finally {
this.currentReqNumber--
if (this.blockQueue.length) {
// 每完成一个就从阻塞队列里剔除一个
this.blockQueue[0]() // 将最先进入阻塞队列的 Promise 从 Pending 变为 Fulfilled
this.blockQueue.shift()
}
}
}
}