Skip to content

Commit

Permalink
context based timers
Browse files Browse the repository at this point in the history
  • Loading branch information
kapv89 committed May 7, 2016
1 parent 61daadb commit cadaeaf
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
"no-spaced-func": 1, // disallow space between function identifier and application
"no-ternary": 0, // disallow the use of ternary operators (off by default)
"no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines
"no-underscore-dangle": 1, // disallow dangling underscores in identifiers
// "no-underscore-dangle": 1, // disallow dangling underscores in identifiers
"one-var": [1, "never"], // allow just one var statement per function (off by default)
"operator-assignment": [1, "never"], // require assignment operator shorthand where possible or prohibit it entirely (off by default)
"padded-blocks": [1, "never"], // enforce padding within blocks (off by default)
Expand Down
284 changes: 230 additions & 54 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,78 +1,254 @@
const timer = {
timeouts: new Map(),
intervals: new Map(),
immediates: new Map(),
animationFrames: new Map(),

setTimeout: (name, fn, interval) => {
timer.clearTimeout(name);
timer.timeouts.set(name, setTimeout(() => {
class Timer {
timeouts = new Map();
intervals = new Map();
immediates = new Map();
animationFrames = new Map();

contextTimers = new WeakMap();

setTimeout(...args) {
if ((typeof args[0]) === 'object') {
return this._setTimeoutContext(...args);
} else {
return this._setTimeoutVanilla(...args);
}
}

_setTimeoutContext(ctx, name, fn, interval) {
if (!this.contextTimers.has(ctx)) {
this.contextTimers.set(ctx, new Timer());
}

this.contextTimers.get(ctx).setTimeout(name, fn, interval);

return this;
}

_setTimeoutVanilla(name, fn, interval) {
this.clearTimeout(name);
this.timeouts.set(name, setTimeout(() => {
fn();
timer.clearTimeout(name);
this.clearTimeout(name);
}, interval));
return timer;
},

clearTimeout: (name) =>{
if (timer.timeouts.has(name)) {
clearTimeout(timer.timeouts.get(name));
timer.timeouts.delete(name);
return this;
}

clearTimeout(...args) {
if ((typeof args[0]) === 'object') {
return this._clearTimeoutContext(...args);
} else {
return this._clearTimeoutVanilla(...args);
}
}

_clearTimeoutContext(ctx, ...args) {
if (!this.contextTimers.has(ctx)) {
return this;
}

if (args.length === 0) {
Array.from(this.contextTimers.get(ctx).timeouts.keys()).forEach((timeout) => {
this.contextTimers.get(ctx).clearTimeout(timeout);
});
} else {
const [timeout] = args;
this.contextTimers.get(ctx).clearTimeout(timeout);
}

return this;
}

_clearTimeoutVanilla(name) {
if (this.timeouts.has(name)) {
clearTimeout(this.timeouts.get(name));
this.timeouts.delete(name);
}

return this;
}

setInterval(...args) {
if ((typeof args[0]) === 'object') {
return this._setIntervalContext(...args);
} else {
return this._setIntervalVanilla(...args);
}
}

_setIntervalContext(ctx, name, fn, interval) {
if (!this.contextTimers.has(ctx)) {
this.contextTimers.set(ctx, new Timer());
}

this.contextTimers.get(ctx).setInterval(name, fn, interval);

return this;
}

_setIntervalVanilla(name, fn, interval) {
this.clearInterval(name);
this.intervals.set(name, setInterval(fn, interval));
return this;
}

return timer;
},
clearInterval(...args) {
if ((typeof args[0]) === 'object') {
return this._clearIntervalContext(...args);
} else {
return this._clearIntervalVanilla(...args);
}
}

setInterval: (name, fn, interval) => {
timer.clearInterval(name);
timer.intervals.set(name, setInterval(fn, interval));
return timer;
},
_clearIntervalContext(ctx, ...args) {
if (!this.contextTimers.has(ctx)) {
return this;
}

clearInterval: (name) => {
if (timer.intervals.has(name)) {
clearInterval(timer.intervals.get(name));
timer.intervals.delete(name);
if (args.length === 0) {
Array.from(this.contextTimers.get(ctx).intervals.keys()).forEach((interval) => {
this.contextTimers.get(ctx).clearTimeout(interval);
});
} else {
const [interval] = args;
this.contextTimers.get(ctx).clearTimeout(interval);
}

return timer;
},
return this;
}

setImmediate: (name, fn) => {
timer.clearImmediate(name);
timer.immediates.set(name, setImmediate(() => {
_clearIntervalVanilla(name) {
if (this.intervals.has(name)) {
clearInterval(this.intervals.get(name));
this.intervals.delete(name);
}

return this;
}

setImmediate(...args) {
if ((typeof args[0]) === 'object') {
return this._setImmediateContext(...args);
} else {
return this._setImmediateVanilla(...args);
}
}

_setImmediateContext(ctx, name, fn) {
if (!this.contextTimers.has(ctx)) {
this.contextTimers.set(ctx, new Timer());
}

this.contextTimers.get(ctx).setImmediate(name, fn);

return this;
}

_setImmediateVanilla(name, fn) {
this.clearImmediate(name);
this.immediates.set(name, setImmediate(() => {
fn();
timer.clearImmediate(name);
this.clearImmediate(name);
}));
return timer;
},

clearImmediate: (name) => {
if (timer.immediates.has(name)) {
clearImmediate(timer.immediates.get(name));
timer.immediates.delete(name);
return this;
}

clearImmediate(...args) {
if ((typeof args[0]) === 'object') {
return this._clearImmediateContext(...args);
} else {
return this._clearImmediateVanilla(...args);
}
}

_clearImmediateContext(ctx, ...args) {
if (!this.contextTimers.has(ctx)) {
return this;
}

if (args.length === 0) {
Array.from(this.contextTimers.get(ctx).immediates.keys()).forEach((immediate) => {
this.contextTimers.get(ctx).clearImmediate(immediate);
});
} else {
const [immediate] = args;
this.contextTimers.get(ctx).clearImmediate(immediate);
}

return timer;
},
return this;
}

requestAnimationFrame: (name, fn) => {
timer.cancelAnimationFrame(name);
timer.animationFrames.set(name, requestAnimationFrame(() => {
_clearImmediateVanilla(name) {
if (this.immediates.has(name)) {
clearImmediate(this.immediates.get(name));
this.immediates.delete(name);
}

return this;
}

requestAnimationFrame(...args) {
if ((typeof args[0]) === 'object') {
return this._requestAnimationFrameContext(...args);
} else {
return this._requestAnimationFrameVanilla(...args);
}
}

_requestAnimationFrameContext(ctx, name, fn) {
if (!this.contextTimers.has(ctx)) {
this.contextTimers.set(ctx, new Timer());
}

this.contextTimers.get(ctx).requestAnimationFrame(name, fn);

return this;
}

_requestAnimationFrameVanilla(name, fn) {
this.cancelAnimationFrame(name);
this.animationFrames.set(name, requestAnimationFrame(() => {
fn();
timer.cancelAnimationFrame(name);
this.cancelAnimationFrame(name);
}));

return timer;
},
return this;
}

cancelAnimationFrame(...args) {
if ((typeof args[0]) === 'object') {
return this._cancelAnimationFrameContext(...args);
} else {
return this._cancelAnimationFrameVanilla(...args);
}
}

_cancelAnimationFrameContext(ctx, ...args) {
if (!this.contextTimers.has(ctx)) {
return this;
}

if (args.length === 0) {
Array.from(this.contextTimers.get(ctx).animationFrames.keys()).forEach((animationFrame) => {
this.contextTimers.get(ctx).cancelAnimationFrame(animationFrame);
});
} else {
const [animationFrame] = args;
this.contextTimers.get(ctx).cancelAnimationFrame(animationFrame);
}

return this;
}

cancelAnimationFrame: (name) => {
if (timer.animationFrames.has(name)) {
cancelAnimationFrame(timer.animationFrames.get(name));
timer.animationFrames.delete(name);
_cancelAnimationFrameVanilla(name) {
if (this.animationFrames.has(name)) {
cancelAnimationFrame(this.animationFrames.get(name));
this.animationFrames.delete(name);
}

return timer;
return this;
}
};
}

module.exports = timer;
module.exports = new Timer();

0 comments on commit cadaeaf

Please sign in to comment.