Last active
August 8, 2017 17:30
-
-
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().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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