如果有n 个请求,你怎么用 Promise 去控制并发?

题目:

实现一个 SuperTask类,其至少具有 add 方法和最大并发数 max,该 add 方法接收函数(返回值为 promise),当当前执行的任务数小于设定值 max 时,立即执行,大于 max,则等待任务空闲时执行该任务,模版代码如下:
        function timeout(time) {
            return new Promise((reslove) => {
                setTimeout(() => {
                    reslove()
                }, time);
            })
        }
        const superTask = new SuperTask()
        function addTask(time, name) {
            superTask
                .add(() => timeout(time))
                .then(() => { console.log(`任务${name}完成`); })
        }
        addTask(10000, 1) // 10000ms后输出:任务1完成
        addTask(5000, 2) // 5000ms后输出:任务2完成
        addTask(3000, 3) // 8000ms后输出:任务3完成
        addTask(4000, 4) // 12000ms后躺出:任务4完成
        addTask(5000, 5) // 15000ms后输出: 任务5完成

这个题目在我遇到的面试中,非常高频,在面试的场景下第一次遇到这个题,不免手忙脚乱,但是实际上逻辑非常简单,设置当前执行任务数 cur,并设计一个数组(模拟队列)。每次添加任务或者任务执行完,都去执行如下逻辑:

  1. 判断 cur 是否小于 max
  2. 小于 max,cur++, 第一个任务出队并执行,并在执行结束后,cur–,再次执行相同逻辑
  3. 大于 max,不做处理

答案如下:

class SuperTask{
  constructor(num = 2) {
    this.max = num; // 记录最大并发数量
    this.cur = 0; // 记录当前在执行中的任务数量
    this.tasks = []; // 保存任务
  }
  add(task) {
      return new Promise((reslove, reject)=>{
        this.task.push({
            task,
            reject,
            reslove
        }); // 每次添加,就是往队列尾部增加任务
        this._run() // 并执行 run 方法
    })
  }
  _run() {
    // 判断是否还有任务,以及当前执行中的任务是否小于并发数量
    while (this.tasks.length && this.cur < this.max) {
      // 取出队列第一个任务
      const {task, reslove, reject} = this.tasks.shift();
      // 记录执行中任务数量 +1
      this.cur++;
      // 执行任务
      task().then(reslove, reject).finally(() => {
        // 任务结束后,执行中任务数量 -1
        this.cur--;
        // 并执行同样的逻辑
        this._run();
      });
    }
  }
}

应用场景

我们实现了一个简单的异步并发任务控制器类,它可以帮助我们管理和执行一系列返回promise对象函数。那么,在实际开发中,这种工具有哪些应用场景呢?

  • 当我们需要对多个网络请求进行批量处理时,例如下载多张图片、上传多个文件、获取多条数据等。
  • 当我们需要对多个文件进行批量操作时,例如读取多个文件内容、写入多个文件数据、删除多个文件等。
  • 当我们需要对多个定时器进行批量管理时,例如设置多个倒计时、取消多个倒计时等。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值