Promise 事件执行控制

实现一个带并发限制的异步调度器Scheduler,最多同时运行两个任务

1.async 版

//异步调度器
class Scheduler {
    constructor(maxNum) {
      //等待执行的任务队列
      this.taskList = []
      //当前任务数
      this.count = 0
      //最大任务数
      this.maxNum = maxNum
    }
      
    async add(promiseCreator) {
       //当当前任务数超出最大任务数就将其加入等待执行的任务队列
      if (this.count >= this.maxNum) {
        await new Promise(resolve => {
          this.taskList.push(resolve)
        })
      }
      this.count++
      const result = await promiseCreator()
      this.count--
      //当其它任务执行完任务队列中还有任务没执行就将其出队并执行
      if (this.taskList.length > 0) {
        this.taskList.shift()()
      }
      return result
    }
  }
  
  const timeout = time => {
    return new Promise(resolve => {
      setTimeout(resolve, time)
    })
  }
  
  const scheduler = new Scheduler(2)
  const addTask = (time, value) => {
    scheduler.add(() => {
      return timeout(time).then(() => {
        console.log(value)
      })
    })
  }
  
  addTask(1000, "1")
  addTask(500, "2")
  addTask(300, "3")
  addTask(400, "4")
  
  //此处输出2 -> 3 ->1 -> 4
  //一开始一、2两个任务进入队列
  //500ms时,2完成,输出2,任务3进入队列
  //800ms时,3完成,输出3,任务4进入队列
  //1000ms时,1完成,输出1
  //1200ms时,4完成,输出4
复制代码

2. promise版

//异步调度器
class Scheduler {
    constructor(maxNum) {
      //等待执行的任务队列
      this.taskList = []
      //等待执行的任务控制队列
      this.handleList = []
      //当前任务数
      this.count = 0
      //最大任务数
      this.maxNum = maxNum
    }

    run(promiseCreator) {
      this.count++
      return promiseCreator().then((res) => {
        this.count--
        if (this.handleList.length) this.handleList.shift()();
        return res
      })
    }
      
    add(promiseCreator) {
       //当当前任务数超出最大任务数就将其加入等待执行的任务队列
      if (this.count >= this.maxNum) {
          const promise = new Promise((resolve) => this.handleList.push(resolve))
          this.taskList.push(promise)
      }
      if (this.taskList.length) {
        return this.taskList.shift().then(() => this.run(promiseCreator))
      }
      return this.run(promiseCreator)
    }
  }

  const timeout = time => {
    return new Promise(resolve => {
      setTimeout(resolve, time)
    })
  }
  
  const scheduler = new Scheduler(2)
  const addTask = (time, value) => {
    scheduler.add(() => {
      return timeout(time).then(() => {
        console.log(value)
      })
    })
  }
  
  addTask(1000, "1")
  addTask(500, "2")
  addTask(300, "3")
  addTask(400, "4")
复制代码

3. promise精简版

//异步调度器
class Scheduler {
    constructor(maxNum) {
      //等待执行的任务队列
      this.taskList = []
      //当前任务数
      this.count = 0
      //最大任务数
      this.maxNum = maxNum
    }

    run() {
      this.count++
      this.taskList.shift()().then((result) => {
        this.count--
        if(this.taskList.length) this.run()
      })
    }
      
    add(promiseCreator) {
       this.taskList.push(() => promiseCreator())
       //当当前任务数小于最大任务数就将其任务执行
       this.count < this.maxNum && this.run()
    }
  }
复制代码
相关文章
相关标签/搜索