我已经看到在Angular 2组件类中使用了以下内容:
setTimeout(()=>{}, 0);
这意味着,在0秒后调用一个空函数。我知道这与Javascript事件模型有关,但完全不了解它。
请使用一些现实示例和一些代码段,解释Angular 2中何时以及为何进行此操作。
答案 0 :(得分:10)
setTimeout(()=>{}, 0);
使Angular对整个应用程序运行更改检测,例如typedefs
zone.js修补异步API(addEventHandler
,setTimeout
,...)并在回调完成后运行更改检测。
答案 1 :(得分:2)
我现在补充一下Gunter的答案,因为它现在很小。
他说:
setTimeout(()=>{}, 0);
使Angular对整个应用程序运行更改检测
这是因为setTimeout
方法已被猴子修补以被截取角度,在拦截时触发更改检测。换句话说,每次调用setTimeout
时都会发生变化检测。
这可以这样做:
const temp = window.setTimeout;
window.setTimeout = (...args) => {
temp(...args)
angular.triggerChangeDetection(); // or w.e they use
}
所以0是让变化检测立即发生而空函数是因为我们不想做任何事情。
答案 2 :(得分:1)
我记得很久以前就问过这个问题了。响应是在一个名为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个间隔,您也是批量执行,并且每个批次都将在最后处理当前作业队列(而不是仅仅在事件队列中构建一堆事件,这将阻塞)。