代码之家  ›  专栏  ›  技术社区  ›  vsync

使用setTimeout实现setInterval

  •  -2
  • vsync  · 技术社区  · 8 年前

    什么是最好的实现方法 setInterval 使用 setTimeout ?

    考虑到被嘲笑的 设置间隔 应该能够被“清除”。

    3 回复  |  直到 8 年前
        1
  •  2
  •   Jonas Wilms    8 年前

    嘲笑 设置间隔 准确地说,国家统计局不得不嘲笑 清除间隔 也是:

    {
      const intervals = new Map();
    
      function setInterval(fn, time, context, ...args) {
        const id = Math.floor(Math.random() * 10000);
        intervals.set(id, setTimeout(function next() {
           intervals.set(id, setTimeout(next, time));
           fn.apply(context, args);
        }, time));
        return id;
      }
    
      function clearInterval(id) { 
        clearTimeout(intervals.get(id));
      }
    }
    

    你可以一如既往地使用它:

     const interval = setInterval(console.log, 100, console, "hi");
    
    clearInterval(interval);
    
        2
  •  0
  •   vsync    8 年前

    下面的代码创建了 setInterval 使用 setTimeout

    function interval(cb, ms){
      var a = {
        clear : function(){
          clearTimeout(a.timer)
        }
      };
      (function run(){
        cb();
        a.timer = setTimeout(run, ms);
      })();
      
      return a;
    }
    
    
    var myInterval_1 = interval(()=>{ console.log(1) }, 1000); // create an "interval" 
    var myInterval_2 = interval(()=>{ console.log(2) }, 1000); // create another "interval" 
    
    // clear the first interval
    setTimeout(()=>{ myInterval_1.clear() }, 4000)
        3
  •  0
  •   Sumer    7 年前

    我有一个没有递归的基于承诺的解决方案:)

    function setInterval1(fn, time) {
        let check = { check: true };
        (async function () {
            for (let i = 0; i < Number.POSITIVE_INFINITY && check.check; i++) {
                await new Promise((resolve) => {
                    setTimeout(() => { fn(); resolve(true); }, time);
                });
            }
        })();
        return check;
    }
    
    let check = setInterval1(() => console.log('hi'), 1000);
    
    function clearInterval1(check) {
        check.check = false;
    }
    
    setTimeout(() => { clearInterval1(check) }, 4000)