ngZone или zone.js: место обезьяньих патчей?

Я изучаю, как работает ngZone в Angular. Я понял, что он выполняет патчирование стандартных асинхронных операций (таких как setTimeout).

Но кто делает исправления обезьян? Библиотека zone.js или сама Angular внутри ngZone? Было бы здорово, если бы вы могли показать конкретное место в исходном коде, где это происходит.

3 ответа

Решение

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

Это явно не простой процесс. Я уверен, что есть еще некоторые крайние случаи, которые зона не исправила.

Исправление обезьян осуществляется Zone.js. В ng_zone.ts загружается zone.ts, которая создает корневую зону и патчи API для обезьян.

NGZone просто разветвляет дочернюю зону с именем angular и обеспечивает обратные вызовы в спецификациях зоны. В этих обратных вызовах он генерирует события, которые дополнительно подписываются в application_ref.ts, и обнаружение изменений запускается.

Monkey Patching: Это делается путем вызова функции Zone.__load_patch() с 2 аргументами. Первым аргументом является идентификатор API-интерфейсов, пропатченных обезьянами, а вторым - функция исправления, которая при выполнении заменяет реальный API браузера на переопределенную версию.

Теперь это только верхушка айсберга. Фактическое волшебство сделано, вызывая patchMethod() из utils.ts. Для случая set/clearTimeOut это делается здесь.

В patchMethod() исходный API сохраняется в локальной переменной, то есть делегате, и возвращается то же самое, что сохраняется в переменной setNative внутри timers.ts.

Для полного рабочего процесса, вы можете обратиться к статье ниже.

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

Другие вопросы по тегам