復雜的時間調度器


需求:設計一個自由可靈活配置的時間調度器,有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();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM