【问题标题】:Debugging Angular's digest cycle: How to find the cause of an infinite loop?调试 Angular 摘要循环:如何找到无限循环的原因?
【发布时间】:2014-07-09 20:46:52
【问题描述】:

我目前正在编写一些带有延迟加载内容 + 控制器的代码。我的代码基本上像this fiddle 一样工作。但是,由于某种原因,我的版本不起作用,而是每当 Angular 尝试更新它的视图时,我都会得到 an infinite digest cycle

当我从这个简单的重复语句中删除 ng-include 时,问题就消失了:

<div class="container" ng-repeat="pageName in pageNames">
  <div ng-include="pageName"></div>
</div>

最奇怪的部分:即使pageNames 从未分配给范围,exact same error 也会出现。两个范围(外部和内部控制器的范围 - 我都有一个)可以完全为空(我检查了 Batarang - 我只有两个空范围),我仍然得到错误。

我的代码有点太复杂了,有太多其他的依赖,所以在这里发布它是没有意义的。它最纯粹的版本是上面的小提琴。我找不到两者之间的逻辑差异。当我用 Batarang 检查我的瞄准镜时,我也没有发现任何可疑之处:

  • 我没有在我的作用域中使用函数
  • 我没有使用$watch
  • 我没有使用ng-model

我的结论是我并没有明确地改变任何东西,所以它一定是 angular 引擎盖下的东西。

我能否以某种方式让 Angular 或 Batarang 告诉我在摘要迭代后哪些范围变量发生了变化,以便我确定导致无限循环的罪魁祸首?

更新:

我终于发现history.pushState 搞砸了一切。我现在正在寻找替代方案,例如$location 服务。尽管如此,我仍然想知道如何调试这类问题。有什么提示吗?

【问题讨论】:

  • 有什么原因为什么你不能在你的开发环境中使用一个未缩小版本的 angularjs 而只是在它的 digest() 函数中设置一个断点?
  • 将开发工具设置为中断所有异常,包括捕获的异常。如果您对缩小代码感到困惑,请删除缩小或漂亮地打印 javascript。

标签: javascript angularjs angularjs-ng-repeat angularjs-ng-include


【解决方案1】:

没有直接的方法来获取在每个摘要中更改的范围变量列表,但是如果您处于紧急调试情况,修改 Angular 的源代码以(临时)执行此操作非常简单。 $digest 代码在这里:

angular.js > src > ng > rootScope.js

如果您查看此方法,您会看到对 watchLog 数组的引用。 AngularJS 使用它来报告有用的错误消息,当它检测到你正在得到的循环时。您可以在此处轻松添加一些 console.log 项目,或维护您自己的数组,以便稍后记录或使用调试器进行检查。你也可以在这里设置断点看看发生了什么。

我不清楚为什么 history.pushState() 会与此有关,因为您最初的问题没有谈到 $location、history 或相关函数的使用。但是,请注意,当路径不是您期望的那样时,创建无限循环是 ngInclude 的一个非常常见的问题。大量服务器端(例如 NodeJS)项目被配置为在找不到资源时返回主页/索引页面,因为它们假设正在进行前端路由。这实际上是一个大问题,因为您最终将主页嵌入到主页中,然后再嵌入另一个副本,等等。我看到这种问题大约每周在 S/O 上发布一次。

对此的一个简单测试是更改您的服务器以针对未找到的任何资源返回一个空的 404。每当有人提到“无限循环”和任何类型的资产加载操作时,我总是推荐这个:ui-router、ngRoute、ngInclude 等。

这在路径中使用相对 URL 时尤其常见。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    相关资源
    最近更新 更多