AngularJS:$ evalAsync vs $ timeout

我已经使用AngularJS了一会儿,并发现需要每隔一段时间使用$超时 (似乎通常是初始化一个jQuery插件)。

最近,我一直在试图得到更好,更深入的理解周期的消化,我碰到$ evalAsync函数。

看来这个函数产生类似的结果$timeout ,只有你不给它延迟。 每次我使用$timeout它一直延迟0,所以现在我想知道如果我应该使用$evalAsync来代替。

两者之间有什么根本的区别? 你会使用哪一种呢? 我想得到什么时候使用哪一个更好的感觉。

我最近在这里回答了这个问题: https : //stackoverflow.com/a/17239084/215945 (这个答案链接到一些与Misko的github交stream。)

总结:

  • 如果代码使用指令中的$ evalAsync排队,那么应该 DOM被Angular操作之后 ,但浏览器呈现之前运行
  • 如果代码使用来自控制器的$ evalAsync进行排队,那么应该 DOM被Angular(和浏览器呈现之前)操作之前运行它 – 很less要这样做
  • 如果代码使用$ timeout进行排队,那么应该 DOM被Angular操作之后运行,并且浏览器呈现之后(在某些情况下可能会导致闪烁)

对于那些构build复杂应用程序的人,请注意对您的select有性能影响。 另外,我想用更多的技术细节来完成Mark的回答:

  • $ timeout(callback)将等待当前的摘要循环完成(即angular度更新所有模型和DOM),然后它将执行它的callback – 可能影响angular度模型 – 然后启动一个完整的$apply在$ root作用域,并重新消化所有的东西。

  • 另一方面, $ evalAsync(callback函数)会将callback添加到当前或下一个摘要循环中。 这意味着如果你在一个摘要循环中(例如在一个ng-click指令中调用的函数中),这将不会等待任何东西,代码将立即执行。 如果你在一个asynchronous调用,例如一个setTimeout ,一个新的摘要周期( $apply )将被触发。

因此,在性能方面,最好调用$evalAsync ,除非在执行代码之前视图是最新的,例如,如果您需要访问某些DOm属性(如元素宽度等),那么重要。

如果你想了解$ timeout,$ evalAsync,$ digest,$ apply之间区别的更多细节,我请你阅读我对这个问题的回答: https : //stackoverflow.com/a/23102223/1501926

另外请务必阅读文档 :

$ evalAsync不保证何时执行expression式,只有:

  • 它将在计划评估的函数(最好在DOM渲染之前)之后执行。
  • 执行expression式之后至less要执行一个$ digest循环。

注意: 如果这个函数是在$ digest循环之外被调用,那么将会计划一个新的$ digest循环 。 但是,鼓励始终调用在$ apply调用中更改模型的代码。 这包括通过$ evalAsync评估的代码。