The cause of

Remember being asked in an interview how to implement a concurrency limit for n requests, and then trying to implement the following over the weekend

The principle of

The main feeling is to put all the requests in an array, pop them out after the request has returned, and then press another request in to execute. Requests are asynchronous, there is no way to control them directly, only async await them.

The code:

class RequestQueue { constructor(list, limit) { this.taskList = list; this.limit = limit; this.carryQueue = this.initCarryQueue(); } initCarryQueue() { return this.taskList.splice(0, this.limit); } async carryAllTasks(callback) { if (typeof callback ! == 'function') { alert('callback must be a function') return } let result = []; while (this.carryQueue.length) { const task = this.carryQueue[0]; try { const res = await task(); result.push(res) } catch (error) { console.log(error) } const next = this.taskList.shift(); next && this.carryQueue.push(next); this.carryQueue.shift() } callback(result) }} // const p1 = function(){return new Promise(...) }const taskList = [p1, p2, p3, p4, p5, p6]const requestQueue = new RequestQueue(taskList, 3, true); requestQueue.carryAllTasks((res) => { console.log(res)})Copy the code

I don’t capture giFs, and the effect is that all requests queue up to be executed one by one, which is obviously unreasonable because not all requests have a causal relationship. So, improve it a little bit.

improved

class RequestQueue { constructor(list, limit, isParallel = false) { this.taskList = list; this.limit = limit; this.carryQueue = this.initCarryQueue(); this.isParallel = isParallel } initCarryQueue() { return this.taskList.splice(0, this.limit); } async carryAllTasks(callback) { if (typeof callback ! == 'function') { alert('callback must be a function') return } let result = []; While (this.carryqueue.length) {if (this.isparallel) {// There is no causality between requests, Try {const promiseList = this.carryqueue.map (task => task())) Because promise.all meets reject. Promise.all becomes reject; const res = await Promise.allSettled(promiseList); result = result.concat(res); } catch (error) { console.log(error) } this.carryQueue = this.carryQueue.concat(this.taskList.splice(0, this.limit)); this.carryQueue.splice(0, this.limit); } else {const task = this.carryQueue[0];} else {const task = this.carryQueue[0]; try { const res = await task(); result.push(res) } catch (error) { console.log(error) } const next = this.taskList.shift(); next && this.carryQueue.push(next); this.carryQueue.shift() } } callback(result) }}Copy the code

An improvement is to push all requests to the limit once they are finished with promise.allSettled. When all requests are completed, the final execution result is received via callback.

The last

Although the quality of the article is not good, mistakes and omissions, or hope that the big guys can be generous after seeing, thank you!