DI / 双向数据绑定中:

用户 -> 内存 :

浏览器提供有User Event触发事件的API,如click,change…等等等;

内存 -> 用户:

浏览器并没有提供数据监测的API,故任何内存数据变动(定时、异步请求、事件触发…导致的数据变动)都无法被Listen,自然也就没办法再处理callback了;

但我们可以基于这些大部分能够产生数据变动的事件进行封装(如:click、mouse-enter、Timeout…),在每次事件发生后,执行完事件后,检查一遍数据的变化,如果数据和上次的值有变化,则执行这个值(注册时)对应的callback(框架中),这个callback可能是view层的一个数据展现,也可能是一段处理function;

在检查数据变化的时候,由于你并不知道这个事件是对哪些数据进行了更改,以及这个事件有可能造成事件之外的其他任何地方的数据更改,所以必须进行一次大检查,将所有“注册”过的值全部检查一遍,一次检查称为一个周期,每次最少检查两遍,因为第二遍用来确认,前一遍的变动中是否有数据的变动,导致了其他数据的变动,如果第二次有变动的话,会再执行一遍,直到最后两次完全一致,则停止检查(其实就是个(递归(遍历))的过程),考虑到内存的消耗和死循环的风险,脏检查每个周期最多递归执行10遍,所以在程序结构设计中,尽量避免数据与数据之间的紧耦合;

所以我们看到的

ng-click,ng-change,ng-blur…就是对各类用户事件的封装
$timeout,$http,$window,$location…就是对各种JS/API事件的封装
ng-model,以及控制器中的数据,就是对值的“注册”
$scope 本质是一个总的事件逻辑的封装容器,同时抽象为数据载体,
实质上数据都存在于浏览器堆内存中
$scope.apply() & $scope.digest() 即Angular中的“数据大检查”的function

所以如果我们使用了非Angular封装的事件改编数据时,要手动执行一次大检查

由于Angular这种脏检查的方法效率不高,如果一个页面绑定的view超过2000个,就可能存在比较明显的性能问题,官方称之为“脏检查”

来源:https://github.com/xufei/blog/issues/10

作者 铁血 汉子 2017年10月22日
2024/11/23/11:12:47pm 2017/10/22/10:01:21
0 3873