自制前端框架Day16.循環(huán)檢測(cè)臟值

完善一下watcher的listenFn函數(shù)

目前的scope代碼很簡(jiǎn)單,watch方法用來注冊(cè)一個(gè)watcher税稼,digest方法用來執(zhí)行所有的watcher,將執(zhí)行后的值和上一次的值進(jìn)行比對(duì),如果不一樣针姿,就執(zhí)行watcher的listen方法:

問題是窗声,如果我想在listen這個(gè)回調(diào)函數(shù)里面拿到新值和舊值進(jìn)行操作相恃,目前是不行的,看看下面的代碼笨觅。

Scope.prototype.$digest=function(){
    var self = this;
    var oldValue,newValue;
    for(var i=0;i<this.$$watchers.length;i++){
        oldValue = this.$$watchers[i].last;
        newValue = this.$$watchers[i].watchFn(self)
        if(oldValue!=newValue){
            this.$$watchers[i].last = newValue;
            this.$$watchers[i].listenFn();//注意這里
        }
    }
}

完善一下吧拦耐,在調(diào)用listenFn的時(shí)候把數(shù)據(jù)傳進(jìn)去,改成這樣:

this.$$watchers[i].listenFn(newValue,oldValue,self);

其實(shí)從這個(gè)角度來看见剩,回調(diào)函數(shù)幾乎就是JAVA中的接口:我們定義了watcher對(duì)象杀糯,我們規(guī)定了watcher對(duì)象要有watchFn和listenFn,我們規(guī)定了listenFn在符合條件的時(shí)候執(zhí)行苍苞,我們規(guī)定了listenFn函數(shù)需要的參數(shù)固翰,用戶只需要寫一個(gè)和我們規(guī)定的listenFn函數(shù)一模一樣的函數(shù)就可以使用。

還有一個(gè)問題羹呵,如果我有兩個(gè)watcher骂际,第一個(gè)watcher執(zhí)行完以后,數(shù)據(jù)是干凈的冈欢,可是第二個(gè)watcher又改變了屬性值歉铝,把數(shù)據(jù)變臟了,這時(shí)候第一個(gè)watcher并不知道凑耻,所以它的listenFn也不會(huì)執(zhí)行太示。
解決這個(gè)問題的思路是:為了防止某個(gè)listenFn在其他watcher不知情的時(shí)候操作其他的數(shù)據(jù),我可以設(shè)置一個(gè)標(biāo)志位拳话,只要listenFn被執(zhí)行過一次先匪,那么這個(gè)標(biāo)志位就是臟的,當(dāng)digest結(jié)束后弃衍,如果這個(gè)標(biāo)志位是臟的呀非,那么就說明在digest的時(shí)候執(zhí)行過listenFn,也許這個(gè)listenFn操作了不該操作的數(shù)據(jù),于是就要再執(zhí)行一次digest岸裙。
這樣看來猖败,先把$digest方法改名為$digestOnce比較好。

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.$$watchers[i].last = newValue;
            this.$$watchers[i].listenFn(newValue,oldValue,self);
            dirty=true;
        }
    }
    return dirty;
}

然后外面再寫一個(gè)循環(huán)降允,來不斷檢測(cè)$digestOnce方法是否返回了dirty恩闻。

Scope.prototype.$digest=function(){
    var dirty;
    do {
        dirty = this.$digestOnce();
    } while (dirty);
}

寫一個(gè)測(cè)試案例跑一下試試:

it('digest循環(huán)', function() {
        var i=0;
        var j=0;
        scope.name='wangji';
        scope.age=22;
        var watchFn1 = function(scope){
            return scope.name
        };
        var listenFn1 = function(newvalue,oldvalue,scope){
            console.log('第'+i+'次執(zhí)行watchFn1');
            console.log('oldvalue:'+oldvalue);
            console.log('newvalue:'+newvalue);
            i++;
        }
        var watchFn2 = function(scope){
            return scope.age
        };
        var listenFn2 = function(newvalue,oldvalue,scope){
            console.log('第'+j+'次執(zhí)行watchFn2');
            console.log('oldvalue:'+oldvalue);
            console.log('newvalue:'+newvalue);
            scope.name='hahaha';
            j++;
        }
        scope.$watch(watchFn1,listenFn1);
        scope.$watch(watchFn2,listenFn2);

        scope.$digest();

    });

能夠如期執(zhí)行:

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市剧董,隨后出現(xiàn)的幾起案子幢尚,更是在濱河造成了極大的恐慌,老刑警劉巖翅楼,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尉剩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡毅臊,警方通過查閱死者的電腦和手機(jī)理茎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來管嬉,“玉大人皂林,你說我怎么就攤上這事◎橇茫” “怎么了础倍?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)求厕。 經(jīng)常有香客問我著隆,道長(zhǎng),這世上最難降的妖魔是什么呀癣? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任美浦,我火速辦了婚禮,結(jié)果婚禮上项栏,老公的妹妹穿的比我還像新娘浦辨。我一直安慰自己,他們只是感情好沼沈,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布流酬。 她就那樣靜靜地躺著,像睡著了一般列另。 火紅的嫁衣襯著肌膚如雪芽腾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天页衙,我揣著相機(jī)與錄音摊滔,去河邊找鬼阴绢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛艰躺,可吹牛的內(nèi)容都是我干的呻袭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼腺兴,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼左电!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起页响,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤篓足,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后拘泞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纷纫,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年陪腌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烟瞧。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诗鸭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出参滴,到底是詐尸還是另有隱情强岸,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布砾赔,位于F島的核電站蝌箍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏暴心。R本人自食惡果不足惜妓盲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望专普。 院中可真熱鬧悯衬,春花似錦、人聲如沸檀夹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炸渡。三九已至娜亿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚌堵,已是汗流浹背买决。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人策州。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓瘸味,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親够挂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旁仿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)孽糖,斷路器枯冈,智...
    卡卡羅2017閱讀 134,701評(píng)論 18 139
  • //Clojure入門教程: Clojure – Functional Programming for the J...
    葡萄喃喃囈語閱讀 3,682評(píng)論 0 7
  • 寫在前面 之前寫博客是為了記錄自己的開發(fā)過程,沒指望有人看办悟,所以寫的非常凌亂尘奏。沒想到的是在這些日子里,竟然會(huì)有其他...
    蚊子爸爸閱讀 382評(píng)論 0 1
  • 悅狗: 時(shí)隔多日又收到我的情書有沒有很激動(dòng)哈哈哈病蛉,不過這次我不會(huì)哭了:) 去年過生日的時(shí)候我倆好像都不...
    5毛毛閱讀 175評(píng)論 0 0
  • /大可 在這變幻莫測(cè)的宇宙炫加,空間無法丈量,天體不計(jì)其數(shù)铺然,只有恰當(dāng)?shù)木嚯x俗孝,恰當(dāng)?shù)年P(guān)系,恰當(dāng)?shù)臈l件魄健,無窮無盡的時(shí)間和極...
    大可這樣看世界閱讀 1,005評(píng)論 0 2