起因
想起之前面试被问到过如何实现一个对n多个请求进行并发限制的问题,然后周末就试着实现以下
原理
主要感觉还是把所有请求放到一个数组里面,通过请求有返回之后把他弹出去,然后再压一个请求进来执行。请求请求都是异步的,没办法控制直接控制,只能通过async await 来转成同步。
上代码:
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)})
我不会截取动图,效果就是所有请求会排队一个个执行,这样显然是不合理的,因为并非所有请求之间都有因果关系。所以,再改进一下。
改良
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) { // 请求之间无因果关系,并列发起请求 try { const promiseList = this.carryQueue.map(task => task()) //此处不能用Promise.all,因为Promise.all遇到reject promise.all的状态直接会变成 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]; 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) }}
改良一下,通过Promise.allSettled 将所有请求执行完毕再统一压进limit 个请求执行。等所有请求完成,通过callback接收最后的执行结果。
最后
虽然文章质量不行,错漏百出,还是希望大佬们看到后可以不吝赐教,拜谢!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!