用原生 js 模拟多线程运行

const startTime = (new Date).getTime()

const todo=(ms)=>{
  return new Promise((res,rej)=>{
    setTimeout(()=>{
      res()
    },ms)
  })
}

class SuperTask {
  constructor(parallelCount){
    // 并发数量
    this.parallelCount = parallelCount
    // 排号队列
    this.queue = []
    // 办理队列
    this.exec_queue = []
  }
  add(todoFn){
    return new Promise((res,rej)=>{
      this.queue.push({
        todoFn,
        res,
        rej
      })
      this.exec()
    })
  }
  exec(){
    if(this.exec_queue.length<this.parallelCount&&this.queue.length){
      const execItem = this.queue.shift()
      this.exec_queue.push(execItem)
      const {todoFn,res} = execItem
      return todoFn().finally(()=>{
        // 异步执行好了
        res()
        // 任务数减一
        this.exec_queue.shift()
        // 下一位
        this.exec()
      })
    }
  }
}

const superTask = new SuperTask(2)

const addTask=(name,ms)=>{
  superTask
  .add(()=>todo(ms))
  .then(()=>{
    console.log(`${Number(((new Date).getTime()-startTime)/1000).toFixed()} 秒后,任务${name}完成`)
  })
}

// 2线程
addTask("1",2000)  // 2秒后,打印 
addTask("2",1000)  // 1秒后,打印 
addTask("3",5000)  // 6秒后,打印 
addTask("4",2000)  // 4秒后,打印 
addTask("5",1000)  // 5秒后,打印 

// 3线程
addTask("1",2000)  //  2秒后,打印
addTask("2",1000)  //  1秒后,打印
addTask("3",5000)  //  5秒后,打印
addTask("4",2000)  //  3秒后,打印
addTask("5",1000)  //  3秒后,打印

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值