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()
    }
  }
複製代碼
相關文章
相關標籤/搜索