Last active
February 25, 2017 01:42
-
-
Save loveqoo/d903cec8fee60b129091917ee5a068f1 to your computer and use it in GitHub Desktop.
Javascript Timer
This file contains 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
/* | |
var t = timer.getTimer(1000); // 1 sec | |
var key1 = t.add(function (){ | |
console.log('1 sec'); | |
}); | |
var key2 = t.add(function (){ | |
console.log('2 sec'); | |
}, 2); // 1 sec, 2 times -> 2 sec | |
timer.stop(); // all timers is stopped. | |
timer.status(); | |
All timers is stopped. | |
------------------------------ | |
timer(1000ms delay, 2 task(s)) | |
timer.start(); // all timers is running. | |
t.cancel(key1); | |
timer.status(); | |
All timers is running. | |
------------------------------ | |
timer(1000ms delay, 1 task(s)) | |
t.add(function () { | |
console.log('run once. good bye.'); | |
return false; | |
}); | |
*/ | |
(function (root, moduleName, factory) { | |
if (typeof define === 'function' && define.amd) { | |
define([moduleName], factory); | |
} else { | |
root[moduleName] = factory(); | |
} | |
}(this, 'timer', function () { | |
var timer = (function (delay, autoStart) { | |
var timerId, subTimers = [], | |
error = function (msg) { throw new Error(msg);}, | |
resourceToggler = function (odd, even){ | |
var flag = true, | |
getOdd = function () { return flag ? odd : even; }, | |
getEven = function () { return flag ? even : odd; }, | |
toggle = function () { flag = !flag; }; | |
return { getOdd:getOdd, getEven:getEven, toggle: toggle }; | |
}, | |
rangeRepeater = function (start, end, callback) { | |
(start >= end) && error('invalid parameters: ' + start + ' >= ' + end); | |
var current = start, | |
update = function () { | |
if (current + 1 <= end) { current += 1;} else { current = start;} | |
}; | |
return { | |
get: function () { | |
var result = current; | |
(typeof callback === 'function') && callback(result); | |
update(); | |
return result; | |
}, | |
reset: function () { | |
current = start; | |
} | |
}; | |
}, subTimersCache = {}, | |
start = function () { | |
if (timerId) { return; } | |
(function runNext() { | |
for (var i = 0; i < subTimers.length; i++ ) { | |
if (subTimers[i]() === false) { subTimers.splice(i, 1);} | |
} | |
timerId = setTimeout(runNext, delay); | |
})(); | |
}, | |
stop = function () { | |
if (!timerId) { return; } | |
clearTimeout(timerId); | |
timerId = 0; | |
}, | |
getTimer = function (subDelay) { | |
if (subTimersCache[subDelay]) { return subTimersCache[subDelay]; } | |
(delay > subDelay || subDelay % delay !== 0) && error('invalid delay'); | |
var repeat = subDelay / delay, waitSet = resourceToggler([],[]), | |
subTimer = (function () { | |
var subscribers = [], | |
add = function (f, times) { | |
if (times > 1) { | |
var repeater = rangeRepeater(1, times); | |
return subscribers.push(function () { | |
if (repeater.get() === times) { return f(); } | |
}) - 1; | |
} | |
return subscribers.push(f) - 1; | |
}, | |
cancel = function (seq) { | |
waitSet.getOdd().push(seq); | |
}, | |
publish = function () { | |
waitSet.toggle(); | |
var cancelList = waitSet.getEven(); | |
for (var j = 0; j < cancelList.length; j++) { | |
subscribers.splice(cancelList[j], 1); | |
cancelList.splice(j, 1); | |
} | |
for (var i = 0; i < subscribers.length; i++) { | |
if (subscribers[i]() === false) { subscribers.splice(i, 1);} | |
} | |
}, | |
status = function () { | |
return 'timer(' + subDelay + 'ms delay, ' + subscribers.length + ' task(s))'; | |
}; | |
return { add: add, cancel: cancel, publish: publish, status: status }; | |
})(); // subTimer | |
if (repeat > 1) { | |
var repeater = rangeRepeater(1, repeat); | |
subTimers.push(function () { | |
if (repeater.get() === repeat) { return subTimer.publish(); } | |
}); | |
} else { | |
subTimers.push(function () { | |
subTimer.publish(); | |
}); | |
} | |
var subTimerWrapped = { | |
add: function () { | |
return subTimer.add.apply(subTimer, arguments); | |
}, | |
cancel: function () { | |
subTimer.cancel.apply(subTimer, arguments); | |
}, | |
status: function () { | |
return subTimer.status.apply(subTimer, arguments); | |
} | |
} | |
subTimersCache[subDelay] = subTimerWrapped; | |
return subTimerWrapped; | |
}, // getTimer | |
status = function (out) { | |
var messages = []; | |
messages.push('All timers is ' + (timerId ? 'running.' : 'stopped.')); | |
messages.push('------------------------------'); | |
for (var key in subTimersCache) { | |
if (!subTimersCache.hasOwnProperty(key)) { continue; } | |
messages.push(subTimersCache[key].status()); | |
} | |
(out || console.log)(messages.join('\r\n')); | |
}; | |
autoStart && start(); | |
return { start: start, stop: stop, getTimer: getTimer, status: status }; | |
})(this.timerDefaultDelay || 100, this.timerAutoStart || false); // timer | |
return timer; | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment