自制前端前端框架 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<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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,027评论 19 139
  • 名称 libev - 一个 C 编写的功能全面的高性能事件循环。 概要 示例程序 关于 libev Libev 是...
    hanpfei阅读 15,416评论 0 5
  • Angular面试题 一、ng-show/ng-hide与ng-if的区别? 第一点区别是,ng-if在后面表达式...
    w_zhuan阅读 5,609评论 0 26
  • 题目,是唐僧说的话,只是这个唐僧不是《西游记》里的唐僧,而是今何在《悟空传》里的唐僧。今天推介的书目,就是我非常喜...
    可乐宝宝阅读 1,500评论 0 2
  • 学习习惯的养成,学习能力的培养,要学会遵守纪律与同学友好相处,此时的孩子各个方面知识有限,有些题目都不能理...
    李翰昆妈妈阅读 217评论 0 0