tob*_*bek 6 angular2-changedetection angular
我无法在插件中进行最小化的再现,但是在我的应用程序中,我有一个无限循环,其中ngDoCheck根组件被无限调用,所以我希望能够识别实际发生了什么变化.
我已经查看了堆栈跟踪中的每个调用,从中放入一个断点,ngDoCheck但找不到任何有用的东西.
我知道,从触发变化检测中变化检测可能会导致这种无限循环的(虽然我想调试模式下,我已经启用,会抓住它),但我不能手动找到这个任何实例.
是否有任何人可以记录或检查,以便洞察导致一轮变化检测的原因?
可能不是很有用,但是在这个循环中有一个堆栈和事物状态的快照:
可能会有点晚,但是对于某人可能仍然有所帮助。
我找到了一些解决方案,可以帮助您找到真正导致CD循环的原因。
正如评论中提到的,第一个是检查sourceTask 的字段,最简单的方法是
// put this in any component which is rendered on the page
public ngDoCheck() {
console.log('doCheck', Zone.currentTask.source);
}
Run Code Online (Sandbox Code Playgroud)
这将输出如下内容:
这已经是东西,您有进一步研究的方向,但是还不是很完美。
为了找到定义操作处理程序的真实位置,我们需要区域的long-stack-trace规范。
// add this, for example, in your polyfills file
import 'zone.js/dist/long-stack-trace-zone';
Run Code Online (Sandbox Code Playgroud)
现在,除了任务源之外,我们还可以检查由长堆栈跟踪准备的数据
public ngDoCheck() {
console.log('doCheck', Zone.currentTask.source, Zone.currentTask.data.__creationTrace_);
}
Run Code Online (Sandbox Code Playgroud)
这将输出一个数组:
我们error对数组中每个条目的属性感兴趣。从0元素开始在控制台中进行调查,然后再进行下一步。
在此属性内将是一个堆栈跟踪,如下所示:
也许这种方式过于复杂,但这是我通过阅读Zone的源代码发现的。如果有人建议一个更简单的解决方案,将非常高兴。
我创建了一个小片段,可以帮助您提取较长的堆栈跟踪
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);
}
Run Code Online (Sandbox Code Playgroud)
用法:
public ngDoCheck() {
console.log(renderLongStackTrace());
}
Run Code Online (Sandbox Code Playgroud)
我发现对于EventTask,区域的long-stack-trace创建了错误的堆栈跟踪,您可以在这里跟踪此问题:https://github.com/angular/zone.js/issues/1195
值得Error.stackTraceLimit = Infinity;在应用程序引导之前进行设置(不适用于生产),因为带有角度+区域的堆栈跟踪可能确实很有效。
| 归档时间: |
|
| 查看次数: |
636 次 |
| 最近记录: |