Skip to content

Commit

Permalink
Updated README.ms
Browse files Browse the repository at this point in the history
  • Loading branch information
ZixiaoWang committed Aug 7, 2018
1 parent 5513218 commit ebd55e4
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 58 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vscode
node_modules
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,22 @@
# Ticker
A javascript Ticker which ticks well in inactive tab.
# Timer
A javascript Timer which works well in inactive tab.

### Why I write this library?
Most of the modern browsers throttled [setTimeout/setInterval](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Reasons_for_delays_longer_than_specified) to more than 1000ms if the page's inactive. In most of the cases, it saves CPU loads while the tabs are inactive, which's a good thing. But in some extreme cases (like sending heart beating packet), it requires the page to have a stable timer.
I've tried to search if there's any methods to prevent browsers throttling timers, but so far it seems like [WebWorker](https://developer.mozilla.org/en/docs/Web/API/Web_Workers_API/Using_web_workers) could be the only solution to prevent throttling.

### How to use it?
```
// Instanize the Timer.
let T = new Timer();
// The same API as window.setTimeout/window.setInterval
T.setTimeout(fn, delay, ...params);
T.setInterval(fn, delay, ...params);
T.clearTimeout(timeoutID);
T.clearInterval(intervalID);
// These are newly added
T.hasTimer(timerID)
T.clearAll()
```
28 changes: 14 additions & 14 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
"use strict";
var WORKER = "\nself.addEventListener(\n 'message',\n function(event){\n var message = event.data.split(':');\n var cmd = message[0];\n var ID = message[1];\n var delay = parseInt(message[2]);\n\n switch(cmd) {\n case 'calibrate':\n self.postMessage('calibrate:' + ID);\n break;\n case 'createTimeout':\n var $timeout = setTimeout(function(){\n self.postMessage('timeout:' + ID + ':' + $timeout);\n }, delay);\n self.postMessage('createTimeout:' + ID + ':' + $timeout);\n break;\n case 'createInterval':\n var $interval = setInterval(function(){\n self.postMessage('interval:' + ID + ':' + $interval);\n }, delay);\n self.postMessage('createInterval:' + ID + ':' + $interval);\n break;\n case 'clearTimeout':\n clearTimeout(ID);\n break;\n case 'clearInterval':\n clearInterval(ID);\n break;\n }\n },\n false\n);\n";
var CubeTimer = /** @class */ (function () {
function CubeTimer() {
var WORKER = "\n self.addEventListener(\n 'message',\n function(event){\n var message = event.data.split(':');\n var cmd = message[0];\n var ID = message[1];\n var delay = parseInt(message[2]);\n\n switch(cmd) {\n case 'calibrate':\n self.postMessage('calibrate:' + ID);\n break;\n case 'createTimeout':\n var $timeout = setTimeout(function(){\n self.postMessage('timeout:' + ID + ':' + $timeout);\n }, delay);\n self.postMessage('createTimeout:' + ID + ':' + $timeout);\n break;\n case 'createInterval':\n var $interval = setInterval(function(){\n self.postMessage('interval:' + ID + ':' + $interval);\n }, delay);\n self.postMessage('createInterval:' + ID + ':' + $interval);\n break;\n case 'clearTimeout':\n clearTimeout(ID);\n break;\n case 'clearInterval':\n clearInterval(ID);\n break;\n }\n },\n false\n );\n";
var Timer = /** @class */ (function () {
function Timer() {
this.intervalMap = new Map();
this.timeoutMap = new Map();
this.timeError = 0;
this.worker = new Worker(URL.createObjectURL(new Blob([WORKER], { type: "application/javascript" })));
this.$setWorkerEventListener();
}
CubeTimer.prototype.calibrate = function () {
Timer.prototype.calibrate = function () {
var now = Date.now();
this.worker.postMessage('calibrate:' + now.toString());
};
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
// var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]);
// var timeoutID = scope.setTimeout(function[, delay]);
// var timeoutID = scope.setTimeout(code[, delay]);
CubeTimer.prototype.setTimeout = function (functionOrCode, delay) {
Timer.prototype.setTimeout = function (functionOrCode, delay) {
var params = [];
for (var _i = 2; _i < arguments.length; _i++) {
params[_i - 2] = arguments[_i];
Expand All @@ -37,7 +37,7 @@ var CubeTimer = /** @class */ (function () {
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
// var intervalID = scope.setInterval(func, delay[, param1, param2, ...]);
// var intervalID = scope.setInterval(code, delay);
CubeTimer.prototype.setInterval = function (functionOrCode, delay) {
Timer.prototype.setInterval = function (functionOrCode, delay) {
var params = [];
for (var _i = 2; _i < arguments.length; _i++) {
params[_i - 2] = arguments[_i];
Expand All @@ -55,21 +55,21 @@ var CubeTimer = /** @class */ (function () {
this.worker.postMessage('createInterval:' + intervalID + ':' + timeDelay);
return intervalID;
};
CubeTimer.prototype.clearTimeout = function (timeoutCode) {
Timer.prototype.clearTimeout = function (timeoutCode) {
var interval = this.intervalMap.get(timeoutCode);
if (interval) {
this.worker.postMessage('clearInterval:' + interval.timer);
this.intervalMap.delete(timeoutCode);
}
};
CubeTimer.prototype.clearInterval = function (intervalCode) {
Timer.prototype.clearInterval = function (intervalCode) {
var interval = this.intervalMap.get(intervalCode);
if (interval) {
this.worker.postMessage('clearInterval:' + interval.timer);
this.intervalMap.delete(intervalCode);
}
};
CubeTimer.prototype.clearAll = function () {
Timer.prototype.clearAll = function () {
var _this = this;
this.timeoutMap.forEach(function (info, key) {
_this.clearTimeout(key);
Expand All @@ -78,10 +78,10 @@ var CubeTimer = /** @class */ (function () {
_this.clearInterval(key);
});
};
CubeTimer.prototype.hasTimer = function (timerCode) {
return (this.timeoutMap.has(timerCode) || this.intervalMap.has(timerCode));
Timer.prototype.hasTimer = function (tikcerID) {
return (this.timeoutMap.has(tikcerID) || this.intervalMap.has(tikcerID));
};
CubeTimer.prototype.$setWorkerEventListener = function () {
Timer.prototype.$setWorkerEventListener = function () {
var _this = this;
this.worker.addEventListener("message", function (event) {
var response = event.data.split(':');
Expand Down Expand Up @@ -145,8 +145,8 @@ var CubeTimer = /** @class */ (function () {
}
});
};
CubeTimer.prototype.$getRandomCode = function () {
Timer.prototype.$getRandomCode = function () {
return (performance.now() * Math.random() * 1000000000).toString(16).replace('.', '');
};
return CubeTimer;
return Timer;
}());
74 changes: 37 additions & 37 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
const WORKER = `
self.addEventListener(
'message',
function(event){
var message = event.data.split(':');
var cmd = message[0];
var ID = message[1];
var delay = parseInt(message[2]);
switch(cmd) {
case 'calibrate':
self.postMessage('calibrate:' + ID);
break;
case 'createTimeout':
var $timeout = setTimeout(function(){
self.postMessage('timeout:' + ID + ':' + $timeout);
}, delay);
self.postMessage('createTimeout:' + ID + ':' + $timeout);
break;
case 'createInterval':
var $interval = setInterval(function(){
self.postMessage('interval:' + ID + ':' + $interval);
}, delay);
self.postMessage('createInterval:' + ID + ':' + $interval);
break;
case 'clearTimeout':
clearTimeout(ID);
break;
case 'clearInterval':
clearInterval(ID);
break;
}
},
false
);
self.addEventListener(
'message',
function(event){
var message = event.data.split(':');
var cmd = message[0];
var ID = message[1];
var delay = parseInt(message[2]);
switch(cmd) {
case 'calibrate':
self.postMessage('calibrate:' + ID);
break;
case 'createTimeout':
var $timeout = setTimeout(function(){
self.postMessage('timeout:' + ID + ':' + $timeout);
}, delay);
self.postMessage('createTimeout:' + ID + ':' + $timeout);
break;
case 'createInterval':
var $interval = setInterval(function(){
self.postMessage('interval:' + ID + ':' + $interval);
}, delay);
self.postMessage('createInterval:' + ID + ':' + $interval);
break;
case 'clearTimeout':
clearTimeout(ID);
break;
case 'clearInterval':
clearInterval(ID);
break;
}
},
false
);
`;

interface TimerInfo {
Expand All @@ -43,7 +43,7 @@ interface TimerInfo {
timer: number;
}

class CubeTimer {
class Timer {
private intervalMap: Map<string, TimerInfo>;
private timeoutMap: Map<string, TimerInfo>;
private worker: Worker;
Expand Down Expand Up @@ -134,8 +134,8 @@ class CubeTimer {
})
}

hasTimer(timerCode: string): boolean {
return (this.timeoutMap.has(timerCode) || this.intervalMap.has(timerCode));
hasTimer(tikcerID: string): boolean {
return (this.timeoutMap.has(tikcerID) || this.intervalMap.has(tikcerID));
}

private $setWorkerEventListener() {
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "ticker",
"name": "timers",
"version": "1.0.0",
"description": "A javascript ticker which ticks well in inactive tabs",
"description": "A javascript timers which works well in inactive tabs",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ZixiaoWang/Ticker.git"
"url": "git+https://github.com/ZixiaoWang/Timer.git"
},
"keywords": [
"javascript",
Expand All @@ -17,7 +17,7 @@
"author": "[email protected]",
"license": "MIT",
"bugs": {
"url": "https://github.com/ZixiaoWang/Ticker/issues"
"url": "https://github.com/ZixiaoWang/Timer/issues"
},
"homepage": "https://github.com/ZixiaoWang/Ticker#readme"
"homepage": "https://github.com/ZixiaoWang/Timer#readme"
}

0 comments on commit ebd55e4

Please sign in to comment.