JS实现一个限流器

Posted 这个少年有点热丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS实现一个限流器相关的知识,希望对你有一定的参考价值。

方法add接受一个返回Promise的函数,同时执行的任务数量不超过两个。

这个一道面试题,限流器保证同时最多只有两个任务在执行,如果任务是异步的,会等待异步任务完成之后,才去执行其他未执行任务。

class Scheduler {
    constructor(maxNum) {
      this.taskList = [];  //{1}
      this.count = 0;
      this.maxNum = maxNum;
    }
    async add(promiseCreator) {
      if (this.count >= this.maxNum) {
        await new Promise((resolve) => {  //{2}
          this.taskList.push(resolve)
        })
      }
      this.count ++;
      const result = await promiseCreator();
      this.count --;
      if (this.taskList.length > 0) {
        this.taskList.shift()();    //{3}
      }
      return result;
    }
}


const scheduler = new Scheduler(2)

const timeout = (time)=>{
    return new Promise(r=>setTimeout(r, time))
}
const addTask = (time, order) => {
    scheduler.add(()=>timeout(time))
        .then(()=>console.log(order))
}

addTask(1000, 1)
addTask(500, 2)
addTask(300, 3)
addTask(400, 4)

//log:2 3 1 4

以上是解答,关键在add方法要怎么实现。

在{1}处定义了一个任务队列。执行add方法,如果此时运行的任务超过了最大限制,就会在{2}处await一个promise,并且把promise的resolve放进任务队列中,这样这个方法就会阻塞在这里,等待promise的完成。而只有在之前的任务完成之后,会去taskList中拿resolve去执行({3}处)。执行完resolve,刚才await的promise才会继续往下执行,去执行被阻塞的任务,如此循环,直到所有任务完成。

以上是关于JS实现一个限流器的主要内容,如果未能解决你的问题,请参考以下文章

angularJS使用ocLazyLoad实现js延迟加载

JavaScript笔试题(js高级代码片段)

JS代码片段:一个日期离现在多久了

限流算法原理和实现

限流从概念到实现

常见的几种限流算法代码实现(JAVA)