自制前端前端框架 Day17. 完善digest

如果digest遇到了死循环该如何处理

假设有两个watcher,在digest的时候互相更改对方的值,这会导致digest遇到死循环。于是应该给digest循环增加一个上限,达到上限却依然有脏值的时候,抛出异常:

Scope.prototype.$digest=function(){
    var dirty;
    var ttl = 10;
    do {
        dirty = this.$$digestOnce();
        if(dirty&&!(ttl--)){
            throw "digest次数到达上限依然不稳定"
        }
    } while (dirty);
}

如果有1000个watcher,每次digest都会把所有watcher跑一遍,效率太差了,怎么办

这个问题的解决思路是这样的:首先,我先记住上一次digest的最后一个脏watcher,比如有100个watcher,每次检测到脏watcher的时候,我都把这个watcher记录到一个变量里,这个变量叫做$$lastDirtyWatch 这个变量只记录一个watcher,就是最后遇到的那个脏watcher:

Scope.prototype.$$digestOnce=function(){
    var self = this;
    var oldValue,newValue,dirty;
    for(var i=0;i

这样一来会有这样的效果,如果第49个watcher是脏的,那么this.$$lastDirtyWatch就指向第49个watcher,然后第55个是脏的,this.$$lastDirtyWatch就不再指向第49个watcher,而指向第55个watcher。
那么很显然:如果我们发现this.$$lastDirtyWatch这个指向第N个watcher,就说明N以后的watcher是干净的。
所以在digest循环的时候,每次检测watcher是否脏的时候,都去做一下对比,看看当前的watcher是不是this.$$lastDirtyWatch指向的那个watcher,如果是的话,就可以处理以后直接跳出循环了,因为后面的watcher都是干净的,没必要再循环一次了。

Scope.prototype.$$digestOnce=function(){
    var self = this;
    var oldValue,newValue,dirty;
    for(var i=0;i

你可能感兴趣的:(自制前端前端框架 Day17. 完善digest)