// javascript 提供了两个定时的函数: setTimeout() & setInterval(); // // 因为浏览器是单线程的, 页面渲染、执行 js 都是一个线程来完成的, 所以用 setInterval( fn, INTERVAL ) // 设定的定期执行的执行间隔可能会有偏差, 因此用 setTimeout() 周期的调用要比 setInterval() 准确些。 // 但是今天看到片文章, 说道 setTimeout() 也有有可能会有延迟, 地址是: // http://blogs.sitepoint.com/2010/06/23/creating-accurate-timers-in-javascript/ // 于是写了个函数封装了下: /** * 定期执行一个函数, setInterval() 的改良版 * fn(function), 定期执行的函数 * INTERVAL(number), fn 执行周期 * hanlder(引用), 用来清除定时器, 调用 accurateInterval 后可以用 clearTimeout( handler.timer ) 来清除定时器 * runAsap(boolean), 设定 fn 是在调用 accurateInterval 时立即执行还是等 INTERVAL 过后执行 */ function accurateInterval( fn, INTERVAL, handler, runAsap ) { var start = new Date().getTime(), time = runAsap ? 0 : INTERVAL; if ( typeof handler !== 'object' ) { // 防止未传参数报错 handler = {}; } runAsap ? _interval() : ( handler.timer = window.setTimeout( _interval, INTERVAL ) ); function _interval() { var latency; if (fn() === false) { return; } time += INTERVAL; latency = time + start - new Date().getTime(); handler.timer = window.setTimeout( arguments.callee, latency ); }; } // console.log( 'set timer "HELLO" at:', new Date().getTime() / 1000 ); accurateInterval( function() { console.log( 'hello', new Date().getTime() / 1000 ); }, 3000, h = {}, 1 ); // console.log( 'set timer "WORLD" at:', new Date().getTime() / 1000 ); accurateInterval( function() { console.log( 'world', new Date().getTime() / 1000 ); }, 2000, w = {}); // // 清除定时器 // clearTimeout( h.timer ); // clearTimeout( w.timer ); // 参考: How JavaScript Timers Work Creating Accurate Timers in JavaScript