> 技术文档 > 并发任务控制【JavaScript】

并发任务控制【JavaScript】


根据下面这段代码实现一个构造函数SuperTask

  • 里面有一个add方法
  • 返回一个Promise
  • 根据代码返回的结果可知,任务并发数为2
function timeout(time) { return new Promise((resolve, reject) => { setTimeout(reject, time); })}const superTask = new SuperTask()function addTask(time, name) { superTask .add(() => timeout(time)) .then(() => { console.log(`任务${name}完成`) }, () => { console.log(`任务${name}失败`) })}// 由这个可知 任务并发数为2addTask(1000, 1) // 10s后输出 任务1已完成addTask(500, 2) // 5s后输出 任务2已完成addTask(300, 3) // 8s后输出 任务3已完成addTask(400, 4) // 10s后输出 任务4已完成addTask(500, 5) // 15s后输出 任务5已完成

代码实现如下

1.代码实现需要的已知条件 parallelCount并发任务数 tasks任务队列 runningCount正在执行的任务

2.add方法返回一个Promise

3.实现一个 _run方法,这个方法类似叫号

  •         执行了一个任务后需要调用这个函数是否还有剩余的执行空间
  •         然后就是一个任务进入任务队列后也需要调用这个函数看是否有剩余的执行空间

4.有一个细节,就是任务队列中传递三个参数{task,resolve,reject},这样的话在_run函数中执行task任务后需要拿到任务成功后的成功回调和失败回调

class SuperTask { constructor(parallelCount = 2) { this.parallelCount = parallelCount // 并发任务数 this.tasks = [] // 正在排队的任务 this.runningCount = 0 // 正在执行的任务 } add(task) { return new Promise((resolve, reject) => { // 加入到任务队列 this.tasks.push({ task, resolve, reject }) this._run() }) } // 询问可以取出一个任务进行处理 _run() { while (this.tasks.length && this.runningCount  { this.runningCount-- this._run() }) this.runningCount++ } }}

附源码:

function timeout(time) { return new Promise((resolve, reject) => { setTimeout(reject, time); })}const superTask = new SuperTask()function addTask(time, name) { superTask .add(() => timeout(time)) .then(() => { console.log(`任务${name}完成`) }, () => { console.log(`任务${name}失败`) })}// 由这个可知 任务并发数为2addTask(1000, 1) // 10s后输出 任务1已完成addTask(500, 2) // 5s后输出 任务2已完成addTask(300, 3) // 8s后输出 任务3已完成addTask(400, 4) // 10s后输出 任务4已完成addTask(500, 5) // 15s后输出 任务5已完成// 实现SuperTaskclass SuperTask { constructor(parallelCount = 2) { this.parallelCount = parallelCount // 并发任务数 this.tasks = [] // 正在排队的任务 this.runningCount = 0 // 正在执行的任务 } add(task) { return new Promise((resolve, reject) => { // 加入到任务队列 this.tasks.push({ task, resolve, reject }) this._run() }) } // 询问可以取出一个任务进行处理 _run() { while (this.tasks.length && this.runningCount  { this.runningCount-- this._run() }) this.runningCount++ } }}