GWT Scheduler中scheduleFinally和scheduleDeferred有什么区别?

时间:2014-08-21 10:40:04

标签: gwt scheduler

我在这个帖子中找不到答案:

Using the GWT Scheduler

GWT Scheduler类具有scheduleDeferred API,该API在浏览器事件循环返回后执行。 scheduleFinally API允许我在控件返回浏览器事件循环之前执行代码。

我如何决定是否应该使用scheduleDeferred或scheduleFinally?是否有代码示例显示行为的差异?

1 个答案:

答案 0 :(得分:9)

要理解这一点,首先需要了解事件循环的基本概念。当您编写要在浏览器中运行的代码时,您不会编写此循环 - 它位于浏览器中,等待用户执行某些操作。当事情发生时(鼠标事件,键盘事件,AJAX调用返回,setTimeout关闭),循环调用您的代码,并让您按照自己的意愿处理它。

首先,我们有scheduleDeferred,这是一种通知浏览器我们有一些代码可以很快运行 ,但不会在这个循环中的方法。这是让浏览器重新获得控制权,渲染一些内容然后再次给予控制权的一种方便方法。这有助于将计算分解为多个块以避免任何“长时间运行的脚本”错误,或者可以是动画的早期尝试(注意:使用浏览器中的实际requestAnimationFrame api或GWT中的AnimationScheduler.get().requestAnimationFrame代替为此)。

接下来,循环中有两个有趣的地方,您可能希望运行代码 - 或者在浏览器将控制权转移给您时,或者在您再次返回控制权之前。在这两个中,结尾通常更有趣:scheduleFinally。这使您可以在当前事件循环中运行一些代码,但直到它的最后。 CssResource在其ensureInjected()方法中使用此策略 - 当您对此方法运行多个不同的调用时,而不是多次调用DOM,它会将它们全部批处理并在事件循环结束时使用scheduleFinally运行它们。

最后一个,每个事件循环的开始由另一个方法 - scheduleEntry管理。从理论上讲,这可以与最终重新实现AngularJS绑定布线的简单版本一起使用。

//event comes in to GWT from the $entry method, and follows these steps
try {
  // 1. run registered scheduleEntry calls

  // 2. run the current event or callback that the browser called us for
} finally {
  // 3. run registered scheduleFinally calls
}

在这些步骤中对scheduleDeferred的任何调用都添加了对 next 事件循环的调用,以作为#2的一部分运行。