加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何识别Angular2中触发一轮变化检测检测的内容(调试ngDoCheck无

发布时间:2020-12-17 07:15:48 所属栏目:安全 来源:网络整理
导读:我无法在插件中进行最小化的再现,但在我的应用程序中,我有一个无限循环,其中根组件中的ngDoCheck被无限调用,所以我希望能够识别实际上是什么改变. 我已经查看了堆栈跟踪中的每个调用,在ngDoCheck中放置一个断点但找不到任何有用的东西. 我知道从变更检测中触
我无法在插件中进行最小化的再现,但在我的应用程序中,我有一个无限循环,其中根组件中的ngDoCheck被无限调用,所以我希望能够识别实际上是什么改变.

我已经查看了堆栈跟踪中的每个调用,在ngDoCheck中放置一个断点但找不到任何有用的东西.

我知道从变更检测中触发变更检测会导致这种无限循环(虽然我认为调试模式,我启用了它,但它会捕获它)但我无法手动找到任何这种情况.

是否有任何人可以记录或检查,以便洞察导致一轮变化检测的原因?

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

ngDoCheck infinite loop

解决方法

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

我发现了一些解决方案可以帮助您找到实际导致CD循环的内容.

第一个,就像在评论中提到的那样,检查Task的源字段,最简单的方法是

// put this in any component which is rendered on the page
  public ngDoCheck() {
    console.log('doCheck',Zone.currentTask.source);
  }

这将输出如下内容:

enter image description here

这已经是事情,你有进一步研究的方向,但它仍然不完美.

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

// 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_);
  }

这将输出一个数组:

enter image description here

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

在这个属性里面将是一个像这样的堆栈跟踪:

enter image description here

也许这种方式过于复杂,但这是我通过阅读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是值得的;在应用程序引导之前(不用于生产),因为具有角度区域的堆栈跟踪可能真的很松散.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读