Angular的NgZone、变更检测、脏检查概念捋一捋

89 阅读2分钟

NgZone这里不做赘述,见Angular NgZone详解

变更检测(Change Detection)

变更检测是 Angular 的核心机制之一,它负责:

  1. 检查组件数据的变化
  2. 更新 DOM 以反映这些变化
  3. 确保 UI 与应用程序状态同步

脏检查(Dirty Checking)

脏检查是 Angular 实现变更检测的具体策略:

  • 通过比较数据当前值和上一次的值来判断是否发生变化
  • 如果值发生变化(即"变脏"),则更新相应的视图

两者关系

  1. 脏检查是实现变更检测的一种方式

    • Angular 使用脏检查作为其默认的变更检测策略
    • 通过定期检查数据是否"变脏"来发现变化
  2. 变更检测是更广泛的概念

    • 变更检测包含整个检测和更新过程
    • 脏检查只是其中的一种检测变化的技术
  3. 工作流程

    • 变更检测周期开始
    • 对每个绑定执行脏检查
    • 如果发现变化,更新相应视图
    • 完成整个变更检测周期

更准确的总结

  1. 默认情况下,Angular 的变更检测机制通过脏检查(Dirty Checking) 来追踪组件数据的变化,并更新视图。
  2. 对于异步操作(如 setTimeoutPromiseHTTP 请求等),Angular 依赖 Zone.js(通过 NgZone 封装)来自动触发变更检测,确保数据变化后 UI 同步更新。

需要补充的细节

  1. 脏检查的范围

    • Angular 的变更检测默认会检查整个组件树(从根组件开始向下遍历),对比数据是否变化("脏"了)。
    • 使用 OnPush 策略时,Angular 会优化检查范围,仅当输入属性(@Input)变化或手动触发时才会检查。
  2. Zone.js / NgZone 的作用

    • Zone.js 拦截了所有异步操作(如 setTimeoutPromiseXHR 等),并在它们完成后通知 Angular 执行变更检测。
    • 如果你在 NgZone 外运行代码(如 this.ngZone.runOutsideAngular(() => {...})),Angular 不会自动触发变更检测,需要手动调用 detectChanges()

更严谨的说法

✅  "Angular 默认通过脏检查机制实现变更检测,而异步操作(如定时器、HTTP 请求)则由 Zone.js 监控,并在完成后自动触发变更检测。"