class Network {
constructor() {
this.concurrency = 0
this.pending = []
}
request(data) {
if (this.concurrency <= 10) {
++this.concurrency
return request({
...data
}).finally(res =>{
--this.concurrency
this.pending.forEach(data => {
this.request(data)
})
return res
})
} else {
this.pending.push(data)
return new Promise(...)
}
}
}
What I am trying to do is to limit the concurrent request to 10, and let the excessive request to queue and return a pending promise until the concurrent request drop from 10...
Obviously the above code wouldn't work because this.pending
is disconnected from the new Promise
...
This is how I did it eventually:
class Network {
constructor() {
this.concurrency = 0
this.pending = []
}
ajax = data => new Promise(resolve => {
if (this.concurrency <= 10) {
++this.concurrency
return resolve( this.send(data) )
} else {
return this.pending.push({ data, resolve })
}
})
send = data => new Promise(resolve => {
return request({
...data
}).finally(res => {
--this.concurrency
if (this.pending.length)
for (let request of this.pending) {
request.resolve( this.ajax(request.data) )
this.pending.shift()
}
})
})
}
class Network {
constructor() {
this.concurrency = 0
this.pending = []
}
async request(data) {
if (this.concurrency > 10) {
await this.queue();
}
// Make the actual request
// Increment the concurrency count
// call `this.next()` after success of every call
}
queue () {
return new Promise((resolve, reject) => {
this.pending.push({resolve, reject});
})
}
next () {
this.concurrency--;
if (this.concurrency < 10 && this.pending.length) {
let newReq = this.pending.splice(0, 1);
newReq.resolve();
}
}
}