ngZone 或 zone.js:猴子修补的地方?

ngZone or zone.js: the place of monkey-patching?

我正在了解 ngZoneAngular 中的工作原理。 我知道它正在对标准异步操作(例如 setTimeout)进行猴子修补。

但是谁在做猴子补丁? zone.js 库或 Angular 本身在 ngZone 中? 如果您能在源代码中显示它发生的具体位置,那就太好了。

Angular 在 zone.js 内运行该区域,并且 zone.js 提供了一个带有补丁 API.

的范围

您可以自己使用 zone.run(...),而不使用 Angular 的任何内容,并获得补丁 API 的所有效果。

另见 https://github.com/angular/zone.js/

给定时器打补丁的代码 https://github.com/angular/zone.js/blob/master/lib/common/timers.ts#L22

区域库必须在浏览器和服务器端项目中工作。所以它比仅仅修补全局函数要复杂一些。

Zone 不仅会修补全局 API,还会在事件对象广播时修补它们。修补是通过 Zone.__load_patch 完成的,您可以看到这些模块中正在修补的内容。

https://github.com/angular/zone.js/blob/master/lib/browser/browser.ts

https://github.com/angular/zone.js/blob/master/lib/node/node.ts

https://github.com/angular/zone.js/blob/master/lib/rxjs/rxjs.ts

这显然不是一个简单的过程。我敢肯定,还有一些区域没有修补的边缘情况。

Monkey 补丁由 Zone.js 完成。在 ng_zone.ts 中,加载了 zone.ts,它创建了根区域以及猴子补丁 API。

NGZone 只是分叉一个名为 'angular' and provides callbacks in zone specifications. In those callbacks, it emits 事件的子区域,这些事件在 application_ref.ts 中被进一步订阅并开始更改检测。

Monkey Patching:这是通过使用重新定义的版本调用 Zone.__load_patch() function with 2 arguments. First argument is the identifier of the monkey-patched APIs and second is the patch function which when executed, replaces 实际浏览器 API 来完成的。

现在,这只是冰山一角。真正的魔法是通过调用 patchMethod() of utils.ts. For set/clearTimeOut case, this is done here 完成的。

在patchMethod()中,原来的api保存在局部变量中,即timers.ts.

里面的delegate and the same is returned which is saved in setNative变量

完整的工作流程,您可以参考下面的文章。

https://medium.com/reverse-engineering-angular/angular-deep-dive-zone-js-how-does-it-monkey-patches-various-apis-9cc1c7fcc321