Skip to content

Instantly share code, notes, and snippets.

@tennisonchan
Last active August 8, 2017 17:30
Show Gist options
  • Save tennisonchan/a494aa0bff87ef77cc4b89f5356723ed to your computer and use it in GitHub Desktop.
Save tennisonchan/a494aa0bff87ef77cc4b89f5356723ed to your computer and use it in GitHub Desktop.
Implement mySetInterval() and myClearInterval() as functions that behave exactly like setInterval() and clearInterval().
/*
Prompt: Implement mySetInterval() and myClearInterval() as functions that behave exactly like setInterval() and clearInterval(). Obviously, you’re not allowed to use setInterval() in your implementation, but everything else is fair game.
Time: This shouldn’t take too long - please don’t spend more than an hour working on it.
Rules: You may consult MDN for documentation, but you may not use any other resources.
Goals: We’re looking for clean code and quick implementation, so please send in your solution as soon as you finish.
*/
// ### MDN setInterval documentation
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
// ### Behaviors
// 1. executes the callback every specified interval
// 2. once the mySetInterval function was run, it returns the intervalID
// 3. calls the myClearInterval function with intervalID can stop the according mySetInterval
// 4. supports 2 forms of input:
// i. `scope.setInterval(func, delay[, param1, param2, ...])` with extra params
// ii. `scope.setInterval(code, delay)` with code in string
// ### Edge Case
// 1. when calling `setInterval` without specifying a valid delay value, the value will be set as 0
// ### Test Cases
// mySetInterval(function(a){console.log('hello1', a)}, 1000, 'abc')
// => hello1 abc
// mySetInterval("console.log('hello2')", 1000)
// => hello2
// mySetInterval(function(a){console.log('hello3', a)}, 'NaN', 'param1')
// => hello3 param1
// mySetInterval()
// => throw TypeError
// mySetInterval('1')
// => nothing happened, same as setInterval('1')
// myClearInterval(intervalID)
(function(window) {
let _timeoutIDMap = {};
let _count = 0;
function init() {
window.mySetInterval = mySetInterval;
window.myClearInterval = myClearInterval;
}
function mySetInterval() {
if(arguments[0] !== undefined) {
let intervalID = `${+new Date()}${_count++}`;
let intervalTimer = new IntervalTimer();
_timeoutIDMap[intervalID] = intervalTimer;
intervalTimer.mySetInterval.apply(intervalTimer, arguments);
return intervalID;
} else {
throw new TypeError("Failed to execute 'setInterval' on 'Window': 1 argument required, but only 0 present.");
}
}
function myClearInterval(intervalID) {
let intervalTimer = _timeoutIDMap[intervalID];
if(intervalTimer) {
intervalTimer.myClearInterval();
delete _timeoutIDMap[intervalID];
}
}
init();
})(window)
function IntervalTimer() {
this.timeoutID = null;
}
IntervalTimer.prototype.mySetInterval = function(callback, timeInterval) {
let args = Array.prototype.slice.call(arguments);
let params = Array.prototype.slice.call(arguments, 2);
// to handle the edge case 1
timeInterval = isNaN(Number(timeInterval)) ? 0 : Number(timeInterval);
this.timeoutID = window.setTimeout(() => {
if(callback instanceof Function) {
callback.apply(window, params);
} else {
window.setTimeout(callback, 0);
}
this.mySetInterval.apply(this, args);
}, timeInterval);
}
IntervalTimer.prototype.myClearInterval = function() {
window.clearTimeout(this.timeoutID);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment