日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

技本功丨知否知否,Redux源码竟如此意味深长(下集)

發布時間:2023/12/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 技本功丨知否知否,Redux源码竟如此意味深长(下集) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上集回顧

Redux是如何使用的?首先再來回顧一下這個使用demo(誰讓這段代碼完整地展示了redux的使用)

如果有小伙伴對這段代碼不是很理解的話,建議先去學習Redux的使用再來看這篇源碼,這樣更加事半功倍。通過上段代碼,我們拆分幾個比較核心的點,我一一列舉一下:

  • action的結構是如何的?
  • 如何去定義一個reducer?
  • combineReducers是如何整合多個reducer的?
  • createStore是如何創建一個store?
  • 5.dispatch拿到action到底干了什么?

  • subscribe是如何監聽狀態發生改變的?
  • getState是如何拿到所有的狀態值的?
  • 上期我們先解決了前三個疑問,這期我們一起來探索后4個問題。

    4、createStore是如何創建一個store?

    首先我們先擼一個createStore架構出來:

    通過這段代碼我們知道了傳參應該是什么樣子和返回了什么。從中我發現了一個問題,createStore接受的是三個參數:1、reducer 2、預加載的state 3、redux-thunk之類的增強器。但是我們平時經常會寫成如下這個樣子:

    我們會在第二個參數就傳入了增強器,這跟源代碼的參數結構不符哎,但是為什么就可以這么用了。接下來我們就看一下,reducer是如何做這個處理的。

    當第二個參數preloadedState的類型是Function的時候,并且第三個參數enhancer未定義的時候,此時preloadedState將會被賦值給enhancer,preloadedState會替代enhancer變成undefined的。有了這么一層轉換之后,我們就可以大膽地第二個參數傳enhancer了。

    解決了這個疑問之后,往下就是解釋一下他返回的值是什么東西,這些解答我們就放在下面做解釋,這里就不做贅述了。不過在接下去之前,我們得搞清楚下面這組變量代表啥意思。

    其中變量isDispatching,作為鎖來用,我們redux是一個統一管理狀態容器,它要保證數據的一致性,所以同一個時間里,只能做一次數據修改,如果兩個action同時觸發reducer對同一數據的修改,那么將會帶來巨大的災難。所以變量isDispatching就是為了防止這一點而存在的。

    5、dispatch拿到action到底干了啥?

    函數dispatch在函數體一開始就進行了三次條件判斷,分別是以下三個:

    1.判斷action是否為簡單對象

    2.判斷action.type是否存在

  • 判斷當前是否有執行其他的reducer操作
  • 當前三個預置條件判斷都成立時,才會執行后續操作,否則拋出異常。在執行reducer的操作的時候用到了try-finally,可能大家平時try-catch用的比較多,這個用到的還是比較少。執行前isDispatching設置為true,阻止后續的action進來觸發reducer操作,得到的state值賦值給currentState,完成之后再finally里將isDispatching再改為false,允許后續的action進來觸發reducer操作。接著一一通知訂閱者做數據更新,不傳入任何參數。最后返回當前的action。

    6、subscribe是如何監聽狀態發生改變的?

    在注冊訂閱者之前,做了兩個條件判斷:

  • 判斷監聽者是否為函數
  • 是否有reducer正在進行數據修改(保證數據的一致性)
  • 接下來執行了函數ensureCanMutateNextListeners,下面我們看一下ensureCanMutateNextListeners函數的具體實現邏輯:

    邏輯很簡單,判斷nextListeners和currentListeners是否為同一個引用,還記得初始變量定義那以及函數dispatch內部那兩處的代碼嗎?

    這兩處將nextListeners和currentListeners引用了同一個數組,而ensureCanMutateNextListeners就是用來判斷這種情況的,當nextListeners和currentListeners為同一個引用時,則做一層淺拷貝,這里用的就是Array.prototype.slice方法,該方法會返回一個新的數組,這樣就可以達到淺拷貝的效果。

    函數ensureCanMutateNextListeners作為處理之后,將新的訂閱者加入nextListeners中,并且返回取消訂閱的函數unsubscribe。函數unsubscribe執行時,也會執行兩個條件判斷:

  • 是否已經取消訂閱(已取消的不必執行)
  • 是否有reducer正在進行數據修改(保證數據的一致性)
  • 通過條件判斷之后,將該訂閱者從nextListeners中刪除。看到這里可能有小伙伴們對currentListeners和nextListeners有這么一個疑問?函數dispatch里面將二者引用同一個數組,為啥這里將二者分別引用兩個值相同的數組?直接用currentListeners不可以嗎?這里這樣做其實也是為了數據的一致性,因為有這么一種的情況存在。當redux在通知所有訂閱者的時候,此時又有一個新的訂閱者加進來了。如果只用currentListeners的話,當新的訂閱者插進來的時候,就會打亂原有的順序,從而引發一些嚴重的問題。

    7、getState是如何拿到所有的狀態值的?

    getState相比較dispatch要簡單許多,返回currentState即可,而這個currentState在每次dispatch得時候都會得到響應的更新。同樣是為了保證數據的一致性,當在reducer操作的時候,是不可以讀取當前的state值的。

    看完是不是已滿腔熱血

    充滿了斗志?

    總結

    以上是生活随笔為你收集整理的技本功丨知否知否,Redux源码竟如此意味深长(下集)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。