异步并发任务的调度器 —— 两种实现方案

实现一个具有并发数量限制的异步任务调度器,可以规定最大同时运行的任务。

方案1、任务队列,自调用,依次执行

useEffect(() => {
  class Scheduler {
    constructor (max) {
      this.max = max; //? 最大执行量
      this.curNum = 0; //? 当前执行的任务数量
      this.taskQueue = []; //? 还未执行的所有任务队列
    }
    async add(asyncFun) {
      if (asyncFun) this.taskQueue.push(asyncFun);
      //* 当前执行的任务量大于等于最大执行量时,阻断
      if (this.curNum >= this.max) return;
      //* 当前执行的任务量小于最大执行量时,执行任务队列中的第一个任务
      try {
        this.curNum++;
        const result = await this.taskQueue.shift()();
        return result;
      } catch(error) {
      } finally {
        this.curNum--;
        this.taskQueue.length && this.add(); //* 当任务队列还有数据时,自调用执行
      }
    }
  }

  const scheduler = new Scheduler(2);
  // 模拟成功的异步任务,接受一个id作为参数,返回一个延迟1秒后resolve的promise对象,值为id * 2
  const successTask = (id) => () => new Promise((resolve) => { setTimeout(() => resolve(id), 2000) });

  // 模拟失败的异步任务,接受一个id作为参数,返回一个延迟1秒后reject的promise对象,值为id * -1
  const failTask = (id) => () => new Promise((_, reject) => { setTimeout(() => reject(id * -1), 3000)})

  scheduler.add(successTask(1));
  scheduler.add(failTask(2));
  scheduler.add(successTask(3));
  scheduler.add(failTask(4));
  scheduler.add(successTask(5));
}, [])

方案2、使用await等待上一个任务执行完毕后,依次执行

useEffect(() => {
  class Scheduler {
    constructor (max) {
      this.max = max; //? 最大执行量
      this.curNum = 0; //? 当前正在执行的任务数量
      this.queue = []; //? 等待队列
    }
    async add (asyncFun) {
      //* 当前执行的任务量大于最大执行量时。需要等待正在执行的任务
      if (this.curNum >= this.max) await new Promise(resolve => this.queue.push(resolve));
      //* 当前执行的任务量小于等于最大执行量时,直接执行
      try {
        this.curNum++;
        const result = await asyncFun();
        return result;
      } catch (error) {
      } finally {
        this.curNum--;
        this.queue.length && this.queue.shift()(); //* 有正在等待的任务时,将等待队列中的第一个任务抽出来,使其等待结束,继续执行
      }
    }
  }

  const scheduler = new Scheduler(2);
  // 模拟成功的异步任务,接受一个id作为参数,返回一个延迟1秒后resolve的promise对象,值为id * 2
  const successTask = (id) => () => new Promise((resolve) => { setTimeout(() => resolve(id), 2000) });

  // 模拟失败的异步任务,接受一个id作为参数,返回一个延迟1秒后reject的promise对象,值为id * -1
  const failTask = (id) => () => new Promise((_, reject) => { setTimeout(() => reject(id * -1), 3000)})

  scheduler.add(successTask(1));
  scheduler.add(failTask(2));
  scheduler.add(successTask(3));
  scheduler.add(failTask(4));
  scheduler.add(successTask(5));
}, [])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值