JS计数器函数执行过程解读(2)

http://www.itjxue.com  2015-08-06 23:10  来源:未知  点击次数: 

2、中央计时器控件

在使用计时器时,出现了一个问题--在处理大量计时器时如何管理它们。在动画处理中你尝试去同步处理大量属性时就尤其重要,你需要一种方法去管理它们。

你的计时器有一个核心的控制将赋予你很大的权力和灵活性,即:

  • 在某个时刻每个页面仅一个计时器运行;
  • 你可以随时暂停和继续计时器;
  • 移除回调函数不过是小菜一碟。

你也必需认识到,增加同步计时器的数量有可能增加浏览器垃圾回收出现的可能性。一般来说,浏览器在搜寻并尝试绑定任何零碎的东西(删除未使用的变量、对象等)。因为它们通常在正常的Javascript引擎管理之外(通过其它线程),这时定时器的问题就尤为严重。一些浏览器能处理这种情况而另外一些浏览器会导致长时的垃圾回收循环出现。你也许会注意到这种问题--当你在一个浏览器中看到的是漂亮、平滑的动画,而在另一个浏览器中动画是走走停停完成的。减少计时器同步应用的数量对此大有裨益(这也是现代浏览器引入类似中央计时器控件构件的原因)。

让我们来看一个例子,我们有多个函数,这些函数分别对单个属性产生动画效果,但它们被一个单独的计时器函数管理。

用计时器队列控制多重动画:

<div id="box" style="position:absolute;">Hello!</div>
var timers = {
 timerID: 0,
 timers: [],
 start: function(){
  if ( this.timerID )
   return;
  (function(){
   for ( var i = 0; i < timers.timers.length; i++ )
    if ( timers.timers[i]() === false ) {
     timers.timers.splice(i, 1);
     i--;
    }
    timers.timerID = setTimeout( arguments.callee, 0 );
  })();
  },
 stop: function(){
  clearTimeout( this.timerID );
  this.timerID = 0;
  },
 add: function(fn){
  this.timers.push( fn );
  this.start();
 }
};
var box = document.getElementsById("box"), left = 0, top = 20;
timers.add(function(){
 box.style.left = left + "px";
 if ( ++left > 50 )
  return false;
});
timers.add(function(){
 box.style.top = top + "px";
 top += 2;
 if ( top > 120 )
  return false;
});

在这我们创建了一个中央控制结构。我们可以添加新的计时器回调函数,并可停止和开始它们的执行。此外,回调函数有能力在任何时候删除自己,只需简单的返回“false”即可(这比通常的clearTimeout模式更容易),让我们逐一分析代码看看它是如何工作的。

起初,所有回调函数连同当前计时器的ID(timers.ID)被存储在一个中央数组中(timers.timers)。核心内容在start()函数内部,在这里我们需要确认得是已没有计时器在运行,如果是那样,就开始我们的中央计时器。

计时器包含一个循环,它遍历所有的回调函数,并按顺序执行它们,它还检查回调函数返回的值,如果是“false”,将从执行中移除。事实证明,这是计时器管理非常简单的方式。

有一点非常重要,用这种方式组织计时器会确保回调函数总是按顺序执行,那样,正常的计时器总是得不到保证(浏览器一个接一个的选择执行)。

定时器的这种组织方式对于大型应用程序或任何形式的真正的Javascript动画至关重要,当我们讨论如何创建跨浏览器动画时,有一种解决方案肯定有助于将来任何形式的应用开发。

(责任编辑:IT教学网)

更多

推荐Javascript/Ajax文章