如何识别Angular2中触发一轮变化检测检测的内容(调试ngDoCheck无
我无法在插件中进行最小化的再现,但在我的应用程序中,我有一个无限循环,其中根组件中的ngDoCheck被无限调用,所以我希望能够识别实际上是什么改变.
我已经查看了堆栈跟踪中的每个调用,在ngDoCheck中放置一个断点但找不到任何有用的东西. 我知道从变更检测中触发变更检测会导致这种无限循环(虽然我认为调试模式,我启用了它,但它会捕获它)但我无法手动找到任何这种情况. 是否有任何人可以记录或检查,以便洞察导致一轮变化检测的原因? 可能不是很有用,但是在这个循环中有一个堆栈和事物状态的快照: 解决方法
可能有点晚了,但仍然可能对某人有所帮助.
我发现了一些解决方案可以帮助您找到实际导致CD循环的内容. 第一个,就像在评论中提到的那样,检查Task的源字段,最简单的方法是 // put this in any component which is rendered on the page public ngDoCheck() { console.log('doCheck',Zone.currentTask.source); } 这将输出如下内容: 这已经是事情,你有进一步研究的方向,但它仍然不完美. 要找到定义动作处理程序的真实位置,我们需要区域的长堆栈跟踪规范. // add this,for example,in your polyfills file import 'zone.js/dist/long-stack-trace-zone'; 除了任务源之外,我们还可以检查由long-stack-trace准备的数据 public ngDoCheck() { console.log('doCheck',Zone.currentTask.source,Zone.currentTask.data.__creationTrace_); } 这将输出一个数组: 我们对数组中每个条目的错误属性感兴趣. 在这个属性里面将是一个像这样的堆栈跟踪: 也许这种方式过于复杂,但这是我通过阅读Zone的源代码找到的. 更新1 我创建了一个小片段,可以帮助您提取长堆栈跟踪 function renderLongStackTrace(): string { const frames = (Zone.currentTask.data as any).__creationTrace__; const NEWLINE = 'n'; // edit this array if you want to ignore or unignore something const FILTER_REGEXP: RegExp[] = [ /checkAndUpdateView/,/callViewAction/,/execEmbeddedViewsAction/,/execComponentViewsAction/,/callWithDebugContext/,/debugCheckDirectivesFn/,/Zone/,/checkAndUpdateNode/,/debugCheckAndUpdateNode/,/onScheduleTask/,/onInvoke/,/updateDirectives/,/@angular/,/Observable._trySubscribe/,/Observable.subscribe/,/SafeSubscriber/,/Subscriber.js.Subscriber/,/checkAndUpdateDirectiveInline/,/drainMicroTaskQueue/,/getStacktraceWithUncaughtError/,/LongStackTrace/,/Observable._zoneSubscribe/,]; if (!frames) { return 'no frames'; } const filterFrames = (stack: string) => { return stack .split(NEWLINE) .filter((frame) => !FILTER_REGEXP.some((reg) => reg.test(frame))) .join(NEWLINE); }; return frames .filter(frame => frame.error.stack) .map((frame) => filterFrames(frame.error.stack)) .join(NEWLINE); } 用法: public ngDoCheck() { console.log(renderLongStackTrace()); } 更新2 我发现对于EventTask,zone的long-stack-trace创建了错误的堆栈跟踪,你可以在这里跟踪这个问题https://github.com/angular/zone.js/issues/1195 更新3 设置Error.stackTraceLimit = Infinity是值得的;在应用程序引导之前(不用于生产),因为具有角度区域的堆栈跟踪可能真的很松散. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |