2

What would be a good approach to best implement setInterval using setTimeout?

Take into account that the mocked setInterval should be able to be "cleared".

9
  • stackoverflow.com/help/self-answer Commented Jun 3, 2018 at 9:48
  • Why do you want to do that? What refrains you form using the built-in implementation? Commented Jun 3, 2018 at 9:51
  • 1
    because I was challenged by someone, for fun. not all programs have real-life purpose, and it's alright to create things for pure fun. Commented Jun 3, 2018 at 9:52
  • In that case would you accept this Q/A as a dupe? There the challenge was even more fun. Or even this one which shows an implementation with a real use case. Commented Jun 3, 2018 at 9:54
  • Of "implementing your own timing function with no real goal". Commented Jun 3, 2018 at 9:59

5 Answers 5

5

Here the intervalId is the reference object that contains the timeoutId. The reference object changes every time the setTimeout is called recursively.

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); 
Sign up to request clarification or add additional context in comments.

Comments

4

To mock setInterval accurately, ons has to mock clearInterval too:

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

And you can use it as always:

 const interval = setInterval(console.log, 100, console, "hi"); clearInterval(interval); 

1 Comment

I might be misreading (on a phone rn) but I think your implementation will make it impossible to clear the interval from the callback.
1

I have a promise based solution without recursion :)

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) 

Comments

0

Below code creates a mock implementation of setInterval using 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)

8 Comments

That doesn't respect the specs at all.
@Kaiido - what specs? what are you talking about? this works, why the downvote?
Because setInterval implementation is specified by some documents, and that you don't apply these specifications, i.e adding a fool-guard against infinity loops.
you are taking all this too seriously. I am only having fun with javascript, a language which I love and code for the last 13 years.
Sorry, but I don't see the fun in this implementation at all.
|
0

Another form to append it in window object and mimic global setInterval and clearInterval

(function (window) { const idMap = {}; window.customSetInterval = (cb, duration) => { let x = null; const loop = (cb) => { const y = setTimeout(() => { cb(); loop(cb); }, duration); if (!idMap[x]) { x = y; } idMap[x] = y; }; loop(cb); return x; }; window.customClearInterval = (x) => { clearTimeout(idMap[x]); }; })(window); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.