├── .gitignore ├── README.md ├── build ├── interval-min.js └── interval.js ├── demo.html ├── gulpfile.js ├── package.json └── src └── interval.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # real-interval 2 | 3 | 如果你用`setTimeout`或`setInterval`实现过网页倒计时功能,你就会发现: 4 | 5 | ``` 6 | 当电脑或者APP休眠了一段时间后,倒计时会出现问题:它比正确的时间慢了。 7 | ``` 8 | 9 | real-interval能解决这个问题。 10 | 11 | 当休眠的电脑被唤醒后,它会计算出正确的运行时间,你的回调函数可以据此显示正确的剩余时间,或者判断何时应该停止倒计时。 12 | 13 | ## 安装 14 | 15 | 你可以通过npm安装real-interval 16 | 17 | ``` 18 | npm install real-interval 19 | ``` 20 | 21 | OR通过脚本引入它: 22 | 23 | ``` 24 | 25 | ``` 26 | 27 | ## 用法 1 28 | 29 | 在经过指定个数的时间间隔后停止 30 | 31 | ```javascript 32 | var timer = new Interval(function(pass){ 33 | 34 | console.log(pass); 35 | 36 | // stop after 24 hours 37 | if(pass == 60*60*24){ 38 | this.stop(); 39 | }; 40 | 41 | }, 1000); 42 | ``` 43 | 44 | 打印结果: 45 | ``` 46 | 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | ... 53 | 86400 54 | ``` 55 | 56 | 这个例子中的 `pass` 是一个计数器, 表示当前经过了多少个1000毫秒。 57 | 58 | ## 用法 2 59 | 60 | 设定执行次数,自动停止 61 | 62 | ```javascript 63 | // automatic stop after 6 seconds 64 | var timer = new Interval(function(pass){ 65 | 66 | console.log(pass); 67 | 68 | }, 1000, 6); 69 | ``` 70 | 71 | 打印结果: 72 | ``` 73 | 1 74 | 2 75 | 3 76 | 4 77 | 5 78 | 6 79 | ``` 80 | 81 | 这个例子中的定时器会在6秒后自动停止。 82 | 83 | ## 用法 3 84 | 85 | 显示剩余时间 86 | 87 | ```javascript 88 | var timer = new Interval(function(pass, surplus){ 89 | 90 | console.log('stop after ' + surplus + ' seconds'); 91 | 92 | }, 1000, 6); 93 | ``` 94 | 95 | 打印结果: 96 | ``` 97 | stop after 5 seconds 98 | stop after 4 seconds 99 | stop after 3 seconds 100 | stop after 2 seconds 101 | stop after 1 seconds 102 | stop after 0 seconds 103 | ``` 104 | 105 | 这个例子会显示距离停止还有多少秒。 106 | 107 | ## 用法 4 108 | 109 | 立即执行 110 | 111 | ```javascript 112 | var timer = new Interval(function(pass, surplus){ 113 | 114 | console.log('stop after ' + surplus + ' seconds'); 115 | 116 | }, 1000, 6, true); 117 | ``` 118 | 119 | 打印结果: 120 | ``` 121 | stop after 6 seconds 122 | stop after 5 seconds 123 | stop after 4 seconds 124 | stop after 3 seconds 125 | stop after 2 seconds 126 | stop after 1 seconds 127 | stop after 0 seconds 128 | ``` 129 | 130 | 这个例子与上个例子不同的地方在于, 回调函数会立即被调用, 而不是1秒之后。 131 | 132 | -------------------------------------------------------------------------------- /build/interval-min.js: -------------------------------------------------------------------------------- 1 | !function(s,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?module.exports=t():s.Interval=t()}(this,function(){"use strict";function s(s,t,i,e){var n,o;if("function"==typeof s)return t||(t=1e3),i||(i=0),n=(new Date).getTime(),o=function(){var e,u;e=(new Date).getTime()-n,u=t-e%t,this.pass=Math.floor(e/t)+1,this.surplus=i-this.pass,setTimeout(function(){return this._stop?void 0:!1===s.call(this,this.pass,this.surplus)?void this.stop():i&&!this.surplus?void this.stop():void o()}.bind(this),u)}.bind(this),this.stop=function(){this._stop=!0},this.pass=0,this.surplus=i-this.pass,e&&s.call(this,this.pass,this.surplus),o(0),this}return s}); -------------------------------------------------------------------------------- /build/interval.js: -------------------------------------------------------------------------------- 1 | ;(function(root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | define([], factory); 4 | } else if (typeof exports === 'object') { 5 | module.exports = factory(); 6 | } else { 7 | root.Interval = factory(); 8 | } 9 | }(this, function() { 10 | 'use strict'; 11 | 12 | function Interval(callback, interval, count, callbackNow) { 13 | 14 | var startTime, tick; 15 | 16 | if(typeof callback !== 'function') return; 17 | if(!interval) interval = 1000; 18 | if(!count) count = 0; 19 | 20 | startTime = new Date().getTime(); 21 | 22 | tick = function() { 23 | 24 | var timespan, wait; 25 | 26 | timespan = new Date().getTime() - startTime, 27 | wait = interval - (timespan % interval); 28 | 29 | this.pass = Math.floor(timespan / interval) + 1; 30 | this.surplus = count - this.pass; 31 | 32 | setTimeout(function() { 33 | if (this._stop) return; 34 | 35 | if ( false === callback.call(this, this.pass, this.surplus) ){ 36 | this.stop(); 37 | return; 38 | } 39 | 40 | if ( count && !this.surplus){ 41 | this.stop(); 42 | return; 43 | } 44 | 45 | tick(); 46 | 47 | }.bind(this), wait); 48 | 49 | }.bind(this); 50 | 51 | this.stop = function() { 52 | this._stop = true; 53 | } 54 | 55 | this.pass = 0; 56 | this.surplus = count - this.pass; 57 | 58 | if(callbackNow){ 59 | callback.call(this, this.pass, this.surplus); 60 | }; 61 | 62 | tick(0); 63 | 64 | return this; 65 | }; 66 | return Interval; 67 | })); 68 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | test 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
start at:
now is:
pass:0
setInterval:0
realInterval:0
41 | 42 | 43 | 86 | 87 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | umd = require('gulp-umd'), 3 | uglify = require('gulp-uglify'), 4 | rename = require('gulp-rename'); 5 | 6 | gulp.task('umd', function() { 7 | return gulp.src('src/interval.js') 8 | .pipe(umd()) 9 | .pipe(gulp.dest('./build')); 10 | }); 11 | 12 | gulp.task('build', ['umd'], function() { 13 | return gulp.src('build/interval.js') 14 | .pipe(uglify()) 15 | .pipe(rename({ 16 | suffix: "-min" 17 | })) 18 | .pipe(gulp.dest('./build')); 19 | }); 20 | 21 | gulp.task('default', ['build'], function(){ 22 | setTimeout(function(){ 23 | console.log('bulid success'); 24 | }, 0); 25 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "real-interval", 3 | "version": "0.0.6", 4 | "description": "a not sleep interval timer.", 5 | "main": "./build/interval.js", 6 | "scripts": { 7 | "build": "gulp" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/hapjs/real-interval.git" 12 | }, 13 | "keywords": [ 14 | "interval", 15 | "timer", 16 | "sleep" 17 | ], 18 | "author": "hapjs ", 19 | "devDependencies": { 20 | "gulp": "^3.9.1", 21 | "gulp-rename": "^1.2.2", 22 | "gulp-uglify": "^1.5.3", 23 | "gulp-umd": "^0.2.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/interval.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function Interval(callback, interval, count, callbackNow) { 4 | 5 | var startTime, tick; 6 | 7 | if(typeof callback !== 'function') return; 8 | if(!interval) interval = 1000; 9 | if(!count) count = 0; 10 | 11 | startTime = new Date().getTime(); 12 | 13 | tick = function() { 14 | 15 | var timespan, wait; 16 | 17 | timespan = new Date().getTime() - startTime, 18 | wait = interval - (timespan % interval); 19 | 20 | this.pass = Math.floor(timespan / interval) + 1; 21 | this.surplus = count - this.pass; 22 | 23 | setTimeout(function() { 24 | if (this._stop) return; 25 | 26 | if ( false === callback.call(this, this.pass, this.surplus) ){ 27 | this.stop(); 28 | return; 29 | } 30 | 31 | if ( count && !this.surplus){ 32 | this.stop(); 33 | return; 34 | } 35 | 36 | tick(); 37 | 38 | }.bind(this), wait); 39 | 40 | }.bind(this); 41 | 42 | this.stop = function() { 43 | this._stop = true; 44 | } 45 | 46 | this.pass = 0; 47 | this.surplus = count - this.pass; 48 | 49 | if(callbackNow){ 50 | callback.call(this, this.pass, this.surplus); 51 | }; 52 | 53 | tick(0); 54 | 55 | return this; 56 | }; --------------------------------------------------------------------------------