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评估的代码。