我有一个类似的问题,可测试性不稳定,我只知道我有一些pendingMacroTasks
. 将这些任务本地化确实有点棘手(您不会遍历整个代码库并寻找setTimeout
.
但是我最终设法做到了。
比较简单的解决方案
您可以做的第一件事是在 Chrome 中打开您的开发工具,按Ctrl+O
,输入zone.js并按Enter
。
这将打开zone.js源文件(不是 Typescript,而是一些东西)。
在zone.js 中查找Zone.prototype.runTask
并在此方法中放置一个断点。在你的应用程序加载后
启用断点,否则它会被击中太多次。
如果您的可测试性不稳定,则可能意味着您有一些重复性的宏任务会重新安排自己的时间。至少我的情况是这样。
如果是这种情况,则在加载应用程序后每 X 次都会触发断点。
一旦断点被命中,go to task.callback.[[FunctionLocation]]
this 将带你到(很可能) some setTimeout
or setInterval
。
要修复它,请在 Angular zone 之外运行它。
有点棘手的解决方案
这涉及调整 Zone.js 代码,但会为您提供更持久的调试信息。
- 去
node_modules/zone.js/dist/zone.js
。
- 寻找 Zone 的构造函数:
function Zone(parent, zoneSpec)
- 在里面添加以下内容:
this._tasks = {}
- 在全局范围内添加计数器变量:
let counter = 0
Zone.prototype.scheduleTask
在调用 to 之前查找并添加以下内容this._updateTaskCount(task,1)
:
task.id = counter++;
this._tasks[task.id] = task;
Zone.prototype.scheduleTask
在调用 to 之前查找并添加以下内容this._updateTaskCount(task,-1)
:
delete this._tasks[task.id]
- 重新编译应用程序并运行它
假设您进行了上述调整,您始终可以像这样访问待处理的任务:
tasks = Object.values(window.getAllAngularTestabilities()[0]._ngZone._inner._tasks)
要获取影响可测试性状态的所有未决宏任务:
tasks.filter(t => t.type === 'macroTask' && t._state === 'scheduled')
之后,与之前的解决方案类似,检查.callback.[[FunctionLocation]]
并通过在 Angular 区域之外运行来修复。