美文网首页自制前端框架Web前端之路让前端飞
自制前端前端框架 Day17. 完善digest

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

作者: 蚊子爸爸 | 来源:发表于2017-06-17 22:26 被阅读43次

    如果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<this.$$watchers.length;i++){
            oldValue = this.$$watchers[i].last;
            newValue = this.$$watchers[i].watchFn(self)
            if(oldValue!=newValue){
                this.$$lastDirtyWatch=this.$$watchers[i];//新加的一句话
                this.$$watchers[i].last = newValue;
                this.$$watchers[i].listenFn(newValue,oldValue,self);
                dirty=true;
            }
        }
        return dirty;
    }
    

    这样一来会有这样的效果,如果第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<this.$$watchers.length;i++){
            oldValue = this.$$watchers[i].last;
            newValue = this.$$watchers[i].watchFn(self)
            if(oldValue!=newValue){
                this.$$lastDirtyWatch=this.$$watchers[i];
                this.$$watchers[i].last = newValue;
                this.$$watchers[i].listenFn(newValue,oldValue,self);
                dirty=true;
            }else{
                if(this.$$watchers[i]===this.$$lastDirtyWatch){
                    return false;
                }
            }
        }
        return dirty;
    }
    

    相关文章

      网友评论

        本文标题:自制前端前端框架 Day17. 完善digest

        本文链接:https://www.haomeiwen.com/subject/mlvbqxtx.html