字节面试题:限制异步请求并发数

371 阅读1分钟

一道经典的字节面试题:现在有20个异步请求需要发送,但是由于某些原因,要求我们必须将同一时刻的并发请求数量控制在3个以内

一、并发控制器的设计思路。

这道题主要考察Promise

思路是:创建一个并发控制器,使用队列来管理执行的请求。设置一个上限,控制同时执行的请求数量。当一个请求完成时,从队列里取出下一个执行。

二、代码

  class ConcurrentController{
    constructor(){
      this.queue = [];
      this.runningNum = 0;
      this.maxRunningNum = 3;
    }
    addTask(task){
      this.queue.push(task);
      this.run();
    }
    run(){
      //判断,如果还有位置,就继续执行
      if(this.runningNum < this.maxRunningNum && this.queue.length > 0){
        this.runningNum++;
        let task = this.queue.shift();
        task().then(()=>{
          this.runningNum--;
          this.run();
        })
      }else{
        //没位置了,就return
        return;
      }
    }
  }


  let concurrentController = new ConcurrentController();
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task1');resolve(1);},1000)}) )
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task2');resolve(1);},1000)}) )
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task3');resolve(1);},1000)}) )
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task4');resolve(1);},1000)}) )
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task5');resolve(1);},1000)}) )
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task6');resolve(1);},1000)}) )
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task7');resolve(1);},1000)}) )
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task8');resolve(1);},1000)}) )
  concurrentController.addTask(()=> new Promise((resolve)=>{setTimeout(()=>{console.log('task9');resolve(1);},1000)}) )