我已经看到在Angular 2组件类中使用了以下内容:
setTimeout(()=>{}, 0);
这意味着,在0秒后调用一个空函数。我知道这与Javascript事件模型有关,但完全不了解它。
请解释何时以及为什么在Angular 2中使用一个小的 现实世界的例子 和一些 代码段。
我已经看到在Angular 2组件类中使用了以下内容:
setTimeout(()=>{}, 0);
这意味着,在0秒后调用一个空函数。我知道这与Javascript事件模型有关,但完全不了解它。
请解释何时以及为什么在Angular 2中使用一个小的 现实世界的例子 和一些 代码段。
setTimeout(()=>{}, 0);
导致Angular为整个应用程序运行更改检测,例如 ApplicationRef.tick
zone.js补丁异步API(addEventHandler
, setTimeout
,...)并在回调完成后运行更改检测。
我会补充Gunter的答案,因为它现在很小。
他说 :
setTimeout(()=>{}, 0);
导致Angular对整个应用程序运行更改检测
这是因为 setTimeout
方法已被猴子修补,以通过角度拦截,在拦截时触发改变检测。换句话说,每次 setTimeout
被称为变化检测发生。
这可以这样做:
window.setTimeout = () => {
//do the usual setTimeout work
angular.triggerChangeDetection(); // or w.e they use
}
所以0是让变化检测立即发生而空函数是因为我们不想做任何事情。
我记得很久以前就问过这个问题了。响应,在一个名为angular-flexslider的github repo中,它是一种组件级别的替代品 $(document).ready(function() {...}))
。
页面加载后,Angular会操纵DOM。当CPU有点繁忙时,有时可以在页面加载后看到角度表达式更新。超时功能确保在角度处理完文档后零代码运行代码。
我从来没有这样做过,现在有了组件生命周期钩子我无法想象你再次需要(也就是说,如果你真的需要)。但从角度来看,这就是我见过的原因。我还可以说我已经看到很多由工程师编写的Angular代码,你对它们有很高的信心(就他们对Angular的知识而言),从来没有见过任何人这样做过。
此外,它还可以确保您要运行的代码位于当前事件循环队列的末尾。它通常用于表现。我曾经为“无限滚动”列表执行类似下面的操作(现在它是所有RxJS,Observables等)。考虑以下代码:
var res = []
function response ( d ) {
var chunk = data.splice ( 0, 1000 );
res = res.concat ( chunk.map ( ...do something ) );
if ( data.length > 0 ) {
setTimeout ( () => { response ( data ) }, 0 );
}
}
因为你是递归调用的 response
通过 setTimeout
要处理块,即使它有0个间隔,你也是批量执行,并且每个批处理都将在当前作业队列的末尾处理(而不是仅仅在事件队列中构建一堆事件,这将是阻止)。