使用setTimeout实现setInterval

时间:2018-06-03 09:41:54

标签: javascript

使用setInterval最佳实施setTimeout的最佳方法是什么?

考虑到模拟的 setInterval 应该能够被清除"。

4 个答案:

答案 0 :(得分:2)

要准确地模拟 setInterval ,ons也必须模拟 clearInterval

{
  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);

答案 1 :(得分:2)

此处 intervalId 是包含 timeoutId 的参考对象。 每次递归调用setTimeout时,参考对象都会更改。

const _setInterval = (callback, delay) => {
  const timerRef = { id: null };
  const timeout = () => {
    timerRef.id = setTimeout(() => {
      callback();
      timeout();
    }, delay);
  }
  timeout();
  return timerRef;
};

const timerRef = _setInterval(() => {
  console.log("Callback");
}, 1000);

setTimeout(() => {
  clearTimeout(timerRef.id);
}, 5000);

答案 2 :(得分:0)

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

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)

答案 3 :(得分:-1)

下面的代码使用setInterval

创建setTimeout的模拟实现

&#13;
&#13;
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)
&#13;
&#13;
&#13;