我一直在使用AngularJS一段时间,并且发现每隔一段时间就需要使用$timeout(似乎通常是初始化一个jQuery插件)。
最近,我一直在努力更好,更深入地了解摘要周期,并且我遇到了$evalAsync函数。
似乎该函数产生与$timeout
类似的结果,只有你没有给它延迟。我每次使用$timeout
时都会延迟0,所以现在我想知道我是否应该使用$evalAsync
。
两者之间是否存在根本差异?你会用哪种情况比另一种情况多?我想更好地了解何时使用哪一个。
答案 0 :(得分:256)
我最近在这里回答了这个问题:https://stackoverflow.com/a/17239084/215945 (该答案链接到与Misko的一些github交流。)
总结:
答案 1 :(得分:57)
对于那些构建复杂应用程序的人,请注意对您的选择会产生性能影响。另外,我想用更多技术细节完成Mark答案:
$ timeout(回调)将等待当前的摘要周期完成(即角度更新所有模型和DOM),然后它将执行其回调 - 可能影响角度模型 - 然后在根$ scope上启动一个完整的$apply
,并重新删除所有内容。
$ evalAsync(回调)会将回调添加到当前或下一个摘要周期。这意味着如果你在一个摘要周期内(例如在一个从某个ng-click
指令调用的函数中),这将不会等待任何事情,代码将立即执行。如果您在异步调用中,例如setTimeout
,则会触发新的摘要周期($apply
)。
因此,就性能而言,最好调用$evalAsync
,除非在执行代码之前视图是最新的很重要,例如,如果您需要访问某些DOm属性,例如元素宽度等。
如果您想了解有关$ timeout,$ evalAsync,$ digest,$ apply之间区别的更多详细信息,我邀请您阅读关于其他问题的答案:https://stackoverflow.com/a/23102223/1501926
另请务必阅读documentation:
$ evalAsync不保证何时执行表达式,只保证:
- 它将在安排评估的函数之后执行(最好在DOM渲染之前)。
- 表达式执行后将执行至少一个$摘要周期。
注意:如果在$ digest周期之外调用此函数,则会安排新的$ digest周期。但是,建议始终在$ apply调用中调用更改模型的代码。这包括通过$ evalAsync评估的代码。