如何确定是什么触发了Angular2(调试ngDoCheck无限循环)中的一轮更改检测?

如何确定是什么触发了Angular2(调试ngDoCheck无限循环)中的一轮更改检测?,angular,angular2-changedetection,Angular,Angular2 Changedetection,我还不能在plunkr中进行最小的复制,但在我的应用程序中,我有一个无限循环,根组件中的ngDoCheck被无限地调用,所以我希望能够识别实际发生的变化 从在ngDoCheck中设置断点开始,我查看了堆栈跟踪中的每个调用,但没有找到任何有用的东西 我知道从change detection内部触发change detection可能会导致这种无限循环,尽管我认为我启用的调试模式会捕获它,但我无法手动找到任何这样的实例 有没有什么可以记录或检查的东西可以让我们深入了解是什么导致了一轮变化检测 可能不

我还不能在plunkr中进行最小的复制,但在我的应用程序中,我有一个无限循环,根组件中的ngDoCheck被无限地调用,所以我希望能够识别实际发生的变化

从在ngDoCheck中设置断点开始,我查看了堆栈跟踪中的每个调用,但没有找到任何有用的东西

我知道从change detection内部触发change detection可能会导致这种无限循环,尽管我认为我启用的调试模式会捕获它,但我无法手动找到任何这样的实例

有没有什么可以记录或检查的东西可以让我们深入了解是什么导致了一轮变化检测

可能不是很有用,但是在这个循环中有一个堆栈快照和状态:


可能有点晚了,但仍可能对某人有所帮助

我找到了一些解决方案,可以帮助你找到CD循环的真正原因

第一个,正如在评论中提到的,是检查任务的源字段,最简单的方法是

//将其放入页面上呈现的任何组件中 公共电话{ console.log'doCheck',Zone.currentTask.source; } 这将输出如下内容:

这已经是一些东西,你有进一步研究的方向,但它仍然不是完美的

要找到定义动作处理程序的真实位置,我们需要zone的长堆栈跟踪规范

//例如,将其添加到polyfills文件中 导入'zone.js/dist/long stack trace zone'; 现在,除了任务源之外,我们还可以检查由长堆栈跟踪准备的数据

公共电话{ console.log'doCheck',Zone.currentTask.source,Zone.currentTask.data.\uu creationTrace\uu; } 这将输出一个数组:

我们对数组中每个条目的错误属性感兴趣。 从0元素开始在控制台中进行调查,然后继续

此属性内将有如下堆栈跟踪:

也许这种方法过于复杂,但这是我通过阅读Zone的源代码所发现的。 如果有人提出更简单的解决方案,我会非常高兴

更新1 我创建了一个小片段,它可以帮助您提取长堆栈跟踪

函数renderLongStackTrace:字符串{ const frames=Zone.currentTask.data,如有; 常量换行符='\n'; //如果要忽略或取消忽略某些内容,请编辑此数组 常量过滤器\u REGEXP:REGEXP[]=[ /checkAndUpdateView/, /callViewAction/, /ExecutedViewsAction/, /ExecuteComponentViewsAction/, /callWithDebugContext/, /debugCheckDirectivesFn/, /区域/, /checkAndUpdateNode/, /debugCheckAndUpdateNode/, /onScheduleTask/, /onInvoke/, /updateDirectives/, /@角度/, /可观察\.\u尝试订阅/, /可观察的, /安全订户/, /Subscriber.js.Subscriber/, /checkAndUpdateDirectiveInline/, /drainMicroTaskQueue/, /GetStackTraceWithunCughTorror/, /LongStackTrace/, /可观察。_区域订阅/, ]; 如果!帧{ 返回“无帧”; } 常量过滤器参数=堆栈:字符串=>{ 返回堆栈 .拆分换行符 .filterframe=>!FILTER_REGEXP.somereg=>reg.testframe .新线; }; 返回帧 .filterframe=>frame.error.stack .mapframe=>filterFramesframe.error.stack .新线; } 用法:

公共电话{ console.logrenderLongStackTrace; } 更新2 我发现对于EventTask,zone的长堆栈跟踪创建了错误的堆栈跟踪,您可以在这里跟踪这个问题

更新3
设置错误是值得的。stackTraceLimit=无穷大;在应用程序引导之前,不用于生产,因为带有angular+zone的堆栈跟踪可能非常长。

我将查看是否创建了可复制的plunker,否则很难判断,因为没有足够的详细信息。我怀疑这只是在某个异步操作后运行的更改检测。可能您有全局侦听器或setInterval@Maximus我想问题的主要部分是,有没有办法找出导致变化检测的原因?它独立于任何可复制的plunkr-但我不确定是否可能。@yurzui此更改检测循环每秒运行100次,完全冻结了UI-我没有任何设置间隔运行得那么快,也无法想象我正在使用的任何异步活动会做那么多事情,除非我正在使用的某个库失控。。。无论哪种方式,只要找出导致任何一轮更改检测的原因就好了。请参阅task.source和callback