问题描述
有一个异步请求列表需要按照顺序分多次执行
分析
任务可以放入一个队列中,每次从队列中获取若干任务异步执行
实现
一次执行的任务放在 Promise.all 中执行,但是如果执行任务中有一个任务花费时间比较长,其它任务消耗时间短就浪费了大量时间,所以采用计数的方式判断是否可以把任务加入任务队列
代码流程
- 构建任务队列
- 需要执行的任务放入队列
- 执行任务,判断是否有任务可以执行,若有任务可以执行,则正在执行的任务队列加一
- 任务执行完毕之后,再回到第 3 部,直至待执行任务队列和当前执行的任务为空时退出程序
具体 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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| class Queue { constructor(maxTask) { this.maxTask = maxTask this.runningTask = 0 this.taskQueue = [] }
push(task) { if (Array.isArray(task)) { task.forEach((t) => { this.taskQueue.push(t) }) } else { this.taskQueue.push(task) }
this.run() }
async runTask(task) { try { this.runningTask++ await task() } catch (e) { console.error(e) } finally { this.run() this.runningTask-- } }
run() { if (this.canRunTask()) { const task = this.taskQueue.shift() this.runTask(task) this.run() } }
canRunTask() { return !this.isEmpty() && this.runningTask < this.maxTask }
isEmpty() { return !this.taskQueue.length } }
const taskQueue = new Queue(3)
const timeList = [100, 300, 500, 900, 600] const taskList = new Array(20).fill(0).map((item, index) => { return () => new Promise((resolve, reject) => { const time = index % timeList.length console.log('task ', index, 'time ', timeList[time], 'start') const timer = setTimeout(() => { clearTimeout(timer) console.log('task ', index, 'time ', timeList[time], 'finished') if (index % 5 === 0) { reject('error') } else { resolve('success') } }, timeList[time]) }) })
taskQueue.push(taskList)
|
附件