首页 > 编程语言 >Angular ngZone 源码解析

Angular ngZone 源码解析

时间:2023-05-16 17:13:26浏览次数:67  
标签:task Zone targetZone param Angular ngZone Task 源码 any

Angular ngZone 源码解析

ngZone 源码中有几个常用的方法,属性,这里做一个整理与总结

Zone.js简介

ZoneJs 职责

  • 拦截异步任务的调度
  • 封装回调函数用于异常处理以及异步操作中zone的跟踪
  • 提供往zone中添加数据的方法
  • 提供上下文特定的最后一帧错误处理
  • 拦截阻塞方法

Zone 的底层异步Task模型

  • MicroTask 微任务,这个是在当前task 之后立刻执行的,不可取消.肯定是在当前的VM turn。
  • MacroTask 宏任务,这个肯定是不在当前的VM turn内的。一个很好定义合理的延迟执行的任务e.g.setTimeout,setInternal,requestAnimationFrame
  • EventTask 事件任务。

Zone 的属性方法。下面是配置项的解构,可以感知到zone 内部会是啥样的

/**
 * Provides a way to configure the interception of zone events.
 *
 * Only the `name` property is required (all other are optional).
 */
interface ZoneSpec {
  /**
   * The name of the zone. Useful when debugging Zones.
   */
  name: string;

  /**
   * A set of properties to be associated with Zone. Use [Zone.get] to retrieve them.
   */
  properties?: {[key: string]: any};

  /**
   * Allows the interception of zone forking.
   *
   * When the zone is being forked, the request is forwarded to this method for interception.
   *
   * @param parentZoneDelegate Delegate which performs the parent [ZoneSpec] operation.
   * @param currentZone The current [Zone] where the current interceptor has been declared.
   * @param targetZone The [Zone] which originally received the request.
   * @param zoneSpec The argument passed into the `fork` method.
   */
  onFork?:
      (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
       zoneSpec: ZoneSpec) => Zone;

  /**
   * Allows interception of the wrapping of the callback.
   *
   * @param parentZoneDelegate Delegate which performs the parent [ZoneSpec] operation.
   * @param currentZone The current [Zone] where the current interceptor has been declared.
   * @param targetZone The [Zone] which originally received the request.
   * @param delegate The argument passed into the `wrap` method.
   * @param source The argument passed into the `wrap` method.
   */
  onIntercept?:
      (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function,
       source: string) => Function;

  /**
   * Allows interception of the callback invocation.
   *
   * @param parentZoneDelegate Delegate which performs the parent [ZoneSpec] operation.
   * @param currentZone The current [Zone] where the current interceptor has been declared.
   * @param targetZone The [Zone] which originally received the request.
   * @param delegate The argument passed into the `run` method.
   * @param applyThis The argument passed into the `run` method.
   * @param applyArgs The argument passed into the `run` method.
   * @param source The argument passed into the `run` method.
   */
  onInvoke?:
      (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function,
       applyThis: any, applyArgs?: any[], source?: string) => any;

  /**
   * Allows interception of the error handling.
   *
   * @param parentZoneDelegate Delegate which performs the parent [ZoneSpec] operation.
   * @param currentZone The current [Zone] where the current interceptor has been declared.
   * @param targetZone The [Zone] which originally received the request.
   * @param error The argument passed into the `handleError` method.
   */
  onHandleError?:
      (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
       error: any) => boolean;

  /**
   * Allows interception of task scheduling.
   *
   * @param parentZoneDelegate Delegate which performs the parent [ZoneSpec] operation.
   * @param currentZone The current [Zone] where the current interceptor has been declared.
   * @param targetZone The [Zone] which originally received the request.
   * @param task The argument passed into the `scheduleTask` method.
   */
  onScheduleTask?:
      (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task) => Task;

  onInvokeTask?:
      (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task,
       applyThis: any, applyArgs?: any[]) => any;

  /**
   * Allows interception of task cancellation.
   *
   * @param parentZoneDelegate Delegate which performs the parent [ZoneSpec] operation.
   * @param currentZone The current [Zone] where the current interceptor has been declared.
   * @param targetZone The [Zone] which originally received the request.
   * @param task The argument passed into the `cancelTask` method.
   */
  onCancelTask?:
      (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task) => any;

  /**
   * Notifies of changes to the task queue empty status.
   *
   * @param parentZoneDelegate Delegate which performs the parent [ZoneSpec] operation.
   * @param currentZone The current [Zone] where the current interceptor has been declared.
   * @param targetZone The [Zone] which originally received the request.
   * @param hasTaskState
   */
  onHasTask?:
      (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
       hasTaskState: HasTaskState) => void;
}
  • get(key:string):any 这个是从properties里面取值
  • wrap<F extends Function>(callback: F, source: string): F;在当前zone 中封装一个函数,当这个函数被执行时,会在当前的zone 中执行。跟apply/bind神似。
  • run<T>(callback: Function, applyThis?: any, applyArgs?: any[], source?: string): T;在当前的zone中执行函数
  • runGuarded<T>(callback: Function, applyThis?: any, applyArgs?: any[], source?: string): T;与上面的方法类似,区别在于异常处理会在当前的zone 中接管,如果没有处理会rethrow.
  • runTask<T>(task: Task, applyThis?: any, applyArgs?: any): T;执行当前zone 中执行一个Task(上面指定的三个task,micro/macro/eventtask)。这个方法属于底层方法.
  • scheduleMicroTask(source: string, callback: Function, data?: TaskData,customSchedule?: (task: Task) => void): MicroTask;
  • scheduleMacroTask(source: string, callback: Function, data?: TaskData, customSchedule?: (task: Task) => void,customCancel?: (task: Task) => void): MacroTask;
  • scheduleEventTask(source: string, callback: Function, data?: TaskData, customSchedule?: (task: Task) => void, customCancel?: (task: Task) => void): EventTask;
  • scheduleTask<T extends Task>(task: T): T;这个方法也是内部方法,上面三种schedule其实是调用的它。定义/安排一个task
  • cancelTask(task: Task): any;
  • fork(zoneSpec: ZoneSpec): Zone;创建一个子Zone,

class 继承关系

  • interface NgZonePrivate extends NgZone
  • class NoopNgZone implements NgZone
    这个是一个空类,啥也不干

直接介绍ngZone

方法

  • runOutsideAngular<T>(fn: (...args: any[]) => T): T,这个经常用,将某个方法的执行置于ngZone 之外。
  • run<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[]): T,将某个方法置于ngZone中执行。
  • runTask<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[], name?: string): T eventtask的方式来执行某个方法。这个方法好像是给angular 用的,会发布一些事件NgZoneEvent: xxx
  • static isInAngularZone(): boolean 判断当前是否在angular zone 里面

属性

  • isStable: boolean用于标记当前的zone 中没有未执行的Micro/Macro Task

事件

  • onUnstable: EventEmitter<any> = new EventEmitter(false)当代码进入angularZone的时候。或者说有代码被ngZone拦截的时候。这个时候一般是发生在VM turn刚开始的时候,也就是一个宏任务开始的时候,例如setTimeout里面的callback函数开始执行的时候。
  • onMicrotaskEmpty: EventEmitter<any>这个标记当前VM Turn里面所有的微任务都执行结束了。这个会指示Angular,你可以做ChangeDetect了。当然Angular的框架在CD的过程中也会参数更多的微任务。所以这个事件会很频繁的被发布。
  • onStable: EventEmitter<any> = new EventEmitter(false)。当最后一个onMicrotaskEmpty被发布后。再也没有微任务了。这个时候会发布这个事件,这个事件一般是在终止VM Turn 的时候发布。意味着Angular 完成了CD,没有未执行的js 代码了。页面完全处于idle 状态。
  • onError: EventEmitter<any>

注意点

  • 宏任务/微任务 跟js事件模型里面的是一致的。ngZone,通过对宏任务/微任务进行拦截。这些任务在ngZone里面统一被称为Task。只是类型不同。这些Task 的执行是在ngZone 里面的,所以ngZone 能够感知到这些事件。其实当宏任务被执行的时候,它在ngZone里面以及被当成了js 的微任务。
  • Angular 框架在onMicrotaskEmpty发出的时候,可能会触发CD.所以这个方法可能会触发多次。

标签:task,Zone,targetZone,param,Angular,ngZone,Task,源码,any
From: https://www.cnblogs.com/kongshu-612/p/17406200.html

相关文章

  • Spring源码:Bean生命周期(五)
    前言在上一篇文章中,我们深入探讨了Spring框架中Bean的实例化过程,该过程包括从Bean定义中加载当前类、寻找所有实现了InstantiationAwareBeanPostProcessor接口的类并调用实例化前的方法、进行实例化、调用applyMergedBeanDefinitionPostProcessors方法等多个步骤,最终生......
  • 08-接口自动化框架-源码
     原文链接:https://www.cnblogs.com/xiehong/p/14841538.html前言:以前弄过好多接口自动化框架的东西,比如httprunner2.0版本实现的接口自动化框架,还有httprunner3.X实现的接口自动化框架,这些都是开源的,实现起来比较简单。以及使用python+unittest+ddt+yaml等工具实现的接口自动......
  • app直播源码,css宽度不固定,水平居中
    app直播源码,css宽度不固定,水平居中1.相对定位:  #box{position:relative;left:50%;float:left;} #inner{position:relative;left:-50%;} ​需考虑浮动带来的问题 2.利用diplay:table来解决: #box{display:table;margin:0auto}/*不支持ie6,ie7*/  3.CSS3fl......
  • 直播系统app源码,滑块效果、slider用法
    直播系统app源码,滑块效果、slider用法    <viewclass="selconbox">    <viewclass="seltit">购买力</view>    <viewclass="progressbox">     <viewclass="zijintit"wx:if="{{price==0}}......
  • pmsm电阻电感磁链常数辨识源码 电阻,电感,磁链常数辨识。 程序
    pmsm电阻电感磁链常数辨识源码电阻,电感,磁链常数辨识。程序在tidsp实现。在ti开源foc框架基础上开发。能够辨识电机电阻,电感,磁链常数。精度较高,能够满足foc控制需要。辨识时间短,大约两秒完成电阻电感辨识。磁链辨识需要电机旋转。多次辨识,结果一致性好。辨识部分代码不包含寄存......
  • 基于STM32F407/STM32H743芯片和SOEM的E therCAT主站源码 提供配套CUBE工程和。
    基于STM32F407/STM32H743芯片和SOEM的EtherCAT主站源码提供配套CUBE工程和。可配套正点原子探索者开发板使用,或任何带以太网口的407/H743板子。支持DC同步。可配合汇川IS620N、埃斯顿ProNet、迈信EP3E、台达A2-E、伟创SD700、松下A5B/A6B和欧姆龙G5系列驱动器使用,或提供想适配的......
  • C#导入CAD DXF格式的图纸文件源码 结合了. net dxf库文件 C#写的CAD DXF格式文件导入
    C#导入CADDXF格式的图纸文件源码结合了.netdxf库文件C#写的CADDXF格式文件导入,自动解析图形文件坐标并显示,看懂源代码就可根据实际要求应用到项目,非常具有学习价值ID:5275638923543619......
  • PLC三菱PLC FX3U-48MRT 源码,原理图,PCBFX3U PLC控制器
    PLC三菱PLCFX3U-48MRT源码,原理图,PCBFX3UPLC控制器资料尺寸:主控芯片:STM32F103VET6电源:DC24V功能:1、1路RS232、1路RS485。2、24路独立输出,PC817光耦隔离,继电器输出;24路独立输入,PC817光耦隔离,独立TTL输入。预留端口。3、4个指示灯:电源、模式、运行、故障4、2路模拟量输入ADC、2......
  • 无人机VESC7500,低压伺服keil源码,可以无感,霍尔单馈,正余弦,ABZ等多种反馈信号,是用非线性
    无人机VESC7500,低压伺服keil源码,可以无感,霍尔单馈,正余弦,ABZ等多种反馈信号,是用非线性磁链观测器,高频注入等多种算法于一身,上位机源码,原理图。没有PCB!最大电流300A,是学习不错的资料。ID:13295688026550883......
  • 开发板三菱FX3U底层源码,总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,
    开发板三菱FX3U底层源码,总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,支持脉冲输出与定位指令(包括PLSY/PWM/PLSR/PLSV/DRVI/DRVA等指令)。对于FX3U,支持波特率9600/19200/38400/57600/115200自适应ID:58199670048570922......