angular的$watch是如何實現的?

上面的圖是$watch的實現,裡面我觀察到,如果調用$watch監聽,只是在 scope.$$watchers隊列 裡面添加監聽器watcher,並沒有循環或者定時器去檢測值的變化,

那如下面的代碼是怎樣的流程來實現的呢?

剛寫完,細心一想,是因為$apply裡面再調用$digest進行檢測嗎?

然而,再看回$watch的代碼,如果參數listener不為function,則為noop,那這個noop又是什麼呢?


`$scope.$apply ` 的時候,會執行你傳給它的函數,並且執行 $rootScope 的 $digest

noop 就是 function(){}, 一個空的函數表達式

如果你想了解更多關於 scope 的原理 , 可以看看 @徐飛 翻譯的 《build you own angularjs》 第一章 Make-Your-Own-AngularJS/01.md at master · xufei/Make-Your-Own-AngularJS · GitHub


謝邀。

幫你找了一些參考資料:

javascript - How does AngularJSs $watch function work?

$watch how the $apply runs a $digest


瀉藥

我不會ng啊……

好在還能幫你看看代碼

權當參考吧

不一定對

第一眼看上去裡面 $parse 是唯一可疑點

然後去拔了下代碼

基本上是實現了個js parse 啊

把AST都解析了

有AST就能方便做手腳了么

全看看不過來

起碼找到 $parse 定義

angular.js/parse.js at fa79eaa816aa27c6d1b3c084b8372f9c17c8d5a3 · angular/angular.js · GitHub

你看它會特殊處理 string 和 function

你這例子里應該進入default流程

調用addInterceptor

(其實內倆特殊處理最後也調的這玩意)

angular.js/parse.js at fa79eaa816aa27c6d1b3c084b8372f9c17c8d5a3 · angular/angular.js · GitHub

這裡是把數據的攔截器都整好了

然後估計$apply時候應該也會跑下 $parse 啥的吧

(沒看這塊代碼)

把AST跟之前整的對上

(字元碼對應到解析後對象)

再過下該對象的監聽列表

就是跟addInterceptor里整好的那些

如果有監聽函數就挨個跑一邊吧

收工睡覺 = _ =


題主所說的不執行循環檢查正是$watch的目的所在,節省臟檢查的性能開銷,這種策略還是值得學習的。


一般js里的noop就是一個空函數,什麼都沒有的意思。watch的藏檢查會在 $digest 進行,無論是用什麼方式觸發臟檢查都會觸發 digest,然後digest會去比較當前的數據和之前的數據的一致性,不是一致的話就會觸發你註冊過的回調。


前面你的理解是對的,$$watchers的遍歷是由digest觸發的,遍歷的時候會逐個調用watcher函數並與它上次返回值做比較,以判斷整個loop是不是還dirty。因為watcher是作為函數調用的,如果不是函數可能有問題,所以給它一個noop確保這種情況下也能執行通過吧


推薦閱讀:

前端框架有哪些典型問題?
React新引擎React Fiber究竟要解決什麼問題?
很迷茫,不知道自己現在是要繼續學習 React.js 還是系統地學習 JS?
vue2 音樂播放器
Phantom.js維護者Slobodin退出,項目未來將何去何從?

TAG:前端開發 | 前端框架 |