zoukankan      html  css  js  c++  java
  • 复杂的时间调度器

    需求:设计一个自由可灵活配置的时间调度器,有a,b,c,d...很多个需要被调度的方法(方法名称的命名可随意),调度有两种形式,一个是顺序调用(例如调度完a后才能调度b),一个是间隔某个时间进行循环调度。用一个统一的方法进行封装可以实现下列的例子:

    1,可以为5秒后调用a,3秒后调用b,10秒后调用。c...z方法不执行(不执行的方法可以设计成不传递参数),那么在第14秒的时候开始重新从0秒循环,又变成第一秒后调用a,3秒后调用b,这样循环往复;

    2,每间隔6秒调用一次a,每间隔4秒调用一次b,c...z方法不执行;

    3,第一秒先执行a,3秒后执行b,但是c却是每间隔3秒执行一次,d是每间隔4秒执行一次,a和b是每4秒进行一次循环;

    4,a不执行,b和c每间隔3秒执行一次,d不执行;

    /**
         *  loop
         *  delay
         *  同步队列
         *  同步延迟队列
         *  异步延迟队列 
         */
        class Schedule {
          constructor() {
            this.asynchroQueueList = [];
            this.asynchroDelayQueueList = [];
            this.asyncDelayQueueList = [];
            this.timer = null;
          }
          // 同步队列,a -> b -> c -> d
          addAsynchro(fn, option) {
            this.asynchroQueueList.push({fn: fn, ...option});
            return this;
          }
          // 同步不延迟队列 a -> b -> c -> d
          addAsynchroDelay(fn, option) {
            this.asynchroDelayQueueList.push({fn: fn, ...option});
            return this;
          }
          // 异步队列 a = b = c
          addAsyncDelay(fn, option) {
            this.asyncDelayQueueList.push({fn: fn, ...option})
            return this;
          }
          runAsynchro() {
            const len = this.asynchroQueueList.length;
            if (len === 0) {
              return;
            }
            let index = 0;
            while(index < len) {
              const fn =this.asynchroQueueList[index].fn;
              fn();
              index ++;
            }
          }
          stop(fn, delay) {
            return new Promise((resolve) => {
              this.timer = setTimeout(() => {
                fn();
                resolve();
              }, delay)
            })
          }
          runAsynchroDelay() {
            const len = this.asynchroDelayQueueList.length;
            if (len === 0) {
              return;
            }
            let index = 0;
            const doloop = (i) => {
              //  console.log(asynchroDelayQueueList)
              const fn = this.asynchroDelayQueueList[i].fn;
    
              // console.time('test'+i)
              let delay = 0;
              let current = this.asynchroDelayQueueList[i];
              if (current.offset && current.offset  > 0) {
                delay = current.offset;
                current.offset = 0;
              } else {
                delay = current.delay;
              }
                this.stop(fn, delay)
                .then(() => {
                  // console.timeEnd('test' + i)
                index ++;
                if (index < len) {
                  doloop(index);
                } else {
                  index = 0;
                  doloop(index);
                }
                })
            }
            doloop(0);
          }
          runAsyncDelay() {
            const len = this.asyncDelayQueueList.length;
            if (len === 0) {
              return;
            }
            let index = 0;
            
            const loop = (fn, delay) => {
              // console.time('test1' + i + 100)
              this.timer = setTimeout(() => {
                fn();
                loop(fn, delay);
              }, delay);
            }
    
            // console.log(this.asyncDelayQueueList[0])
            for (let i = 0; i < len; i ++) {
              loop(this.asyncDelayQueueList[i].fn, this.asyncDelayQueueList[i].delay);
            }
           
          }
          run() {
            this.runAsyncDelay();
            this.runAsynchro();
            this.runAsynchroDelay();
          }
        }
    
        function a() {
          console.log('aaaaaaaaaaaaaaaaaaaaaaaaaa');
        }
        function b() {
          console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
        }
        function c() {
          console.log('cccccccccccccccccccccccccccccccccc');
        }
        function d() {
          console.log('ddddddddddddddddddddddddddddddd');
        }
    
        // 1,可以为5秒后调用a,3秒后调用b,10秒后调用。c...z方法不执行(不执行的方法可以设计成不传递参数),那么在第14秒的时候开始重新从0秒循环,又变成第一秒后调用a,3秒后调用b,这样循环往复;
        // const schedule = new Schedule();
        // schedule.addAsynchroDelay(a, { delay: 3000, offset: 5000}).addAsynchroDelay(b, { delay: 3000}).addAsynchroDelay(c, { delay: 14000})
        // schedule.run();
        // 3,第一秒先执行a,3秒后执行b,但是c却是每间隔3秒执行一次,d是每间隔4秒执行一次,a和b是每4秒进行一次循环;
        const schedule1 = new Schedule();
        schedule1.addAsynchroDelay(a, { delay: 1000 })
        .addAsynchroDelay(b, { delay: 3000 })
        .addAsyncDelay(c, { delay: 3000 })
        .addAsyncDelay(d, { delay: 4000})
        schedule1.run();
        // 2,每间隔6秒调用一次a,每间隔4秒调用一次b,c...z方法不执行;
        // const schedule2 = new Schedule();
        // schedule2.addAsyncDelay(a, { delay: 4000 }).addAsyncDelay(b, { delay: 4000 })
        // schedule2.run()
        // 4,a不执行,b和c每间隔3秒执行一次,d不执行;
        // const schedule3 = new Schedule();
        // schedule3.addAsyncDelay(b, { delay: 3000 }).addAsyncDelay(c, { delay: 3000 })
        // schedule3.run();
  • 相关阅读:
    JavaScript设计模式与开发实践 适配器模式
    JavaScript设计模式与开发实践 状态模式
    JavaScript设计模式与开发实践 装饰者模式
    JavaScript设计模式与开发实践 中介者模式
    JavaScript设计模式与开发实践 职责链模式
    meta标签属性
    在制作网站之前,前端程序员应该考虑哪些技术细节?
    JavaScript设计模式与开发实践 享元模式
    JavaScript设计模式与开发实践 模板方法模式
    梯度下降法
  • 原文地址:https://www.cnblogs.com/h5it/p/13037512.html
Copyright © 2011-2022 走看看