国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Flux用過了,Redux也用過了,還是覺得不順手?要不要自己造一個?

李世贊 / 2483人閱讀

摘要:前言很多同學用過了,也用過了,但還是覺得不稱心要不要自己造一個一百行來代碼就基本搞定,其實,自己造的框架實不實用,并不重要,重要的是思想。總線根據路由表,調用對應的進行處理。

1 前言

很多同學用過了Flux,也用過了Redux,但還是覺得不稱心?要不要自己造一個?一百行來代碼就基本搞定,So easy, so good!

其實,自己造的框架實不實用,并不重要,重要的是思想。有了設計框架的思想后,再去看人家的框架,就會更多地關注人家為何要這么設計?好處在哪?弊端在哪?是否有改進的地方?明白了框架設計者的想法,才能更好地使用框架。

現在,咱們就一起來設計一個React框架,這個框架具備以下幾個的特點:

單向數據流:業務數據從UI層觸發,經處理到Module層便結束,不再需要人為地將數據反映到UI層。

消息機制:組件與服務之間通過消息總線完成,包括組件與組件之間的嵌套關系。

咱們給這個框架起個響亮的名字——Rebus(React-Bus)。這里的Bus不是公交車的Bus,是計算機基礎原理中“Bus”(總線)。很顯然,咱們要用“消息總線”這樣的思想,實現ReactJs的單向數據流開發模式。一句話概括咱們的框架:Rebus是一個基于消息總線的,單向數據流的,ReactJs開發框架

這里是用Rebus寫的一個TodoMVC實例:https://github.com/odebo/todomvc-rebus(看在我的代碼寫得如此粗糙的份上,大蝦們賞顆星星鼓勵鼓勵下唄)。

2 什么是單向數據流模式

什么是“單向數據流模式”?這個概念對很多人來說可能有點陌生。下面是Facebook的Flux官網(http://facebook.github.io/flux/)提供的說明圖:

好像有點抽象?那咱們先補補腦,看看什么是雙向數據流模式。

什么是雙向數據模式?簡單地說就是UI層的一個操作經過UI層(View)、控制層(Control)、模式層(Model),做完增、刪、改、查等處理后,還得反過來,手動地將增刪改查后的數據反映到UI層上。這就雙向數據流模式。

而Flux中所謂的單向數據流模式是指:UI層監聽應用的“狀態”,當一個操作(Action)經過Dispatch(分發器)、Store(狀態容器),最后更新了“狀態”,UI層自動根據“狀態”的變化而更新界面。

這里的“狀態”是指一個應用某個時刻的某個狀態:比如左側菜單欄展開與否——狀態;導航中高亮項是誰——狀態;用戶是否登錄,用戶是誰——狀態;Table中多少個Item,分別是什么內容——狀態。

簡單地說,單向數據流就是單向綁定,UI層與狀態綁定,當狀態發生變化,UI層自動更新。

可能有的同學會問,既然有AngularJs這樣的雙向綁定的MVVM模式,還搞什么單向綁定模式,聽起來弱爆了。雙向綁定肯定比單向綁定高大上得多。

這個問題不太好下結論,雙向綁定固然有雙向綁定的好處,但也有它的弊端。而相比單向數據流的邏輯處理思路更加單純清晰。

3 Rebus 框架的數據流模型

理解了單向數據流后,咱們給出Rebus框架的數據流模式(如下圖)。概括起來就三個步驟:

UI層觸發的一個Action。

Rebus總線根據Action路由表選擇對應的Service進行處理。

Service處理后,更新狀態(State),結束。

這里的Services層指的是業務服務層,提供業務處理接口,包括對狀態的修改,對后臺數據的異步處理等等。如果覺得這一層太厚,可以分離出專門的Modle接口層。但不管怎樣,一個業務操作從UI層到最后修改狀態便結束,數據流方向只有一個。

但光這么說還是太抽象了,咱們直接上代碼,看看在TodoMVC這個例子中,添加一個新的Todo這個操作是怎么被處理的。

是不是挺簡單,簡潔的三層結構,清晰的數據流:

ReactJs組件只負責渲染和觸發Action,具體誰來響應Action,它不管。

Rebus總線根據Action路由表,調用對應的Service進行處理。

Service層進行完邏輯處理后,通過Rebus.setState()方法更新狀態。

但你一定會問:React組件是怎么監聽狀態的變化的?其實很簡單,直接看代碼:比如咱們希望添加新的Todo后,TodoBody組件會自動更新。所以TodoBody組件應該監聽狀態“todos”的變化。

4 Rebus中的action

用過Flux的同學都知道Flux中有個叫Dispatch的模塊,用來dispatch各種Action。而咱們的Rebus.execute()的作用與Dispatch.dispatch()差不多(如下圖)。

不一樣的是Rebus.execute(actionHead, arg1,arg2,…)的第一個參數是action頭,其它參數直接跟在action頭后面。Action頭中包含兩個信息:要做什么?從哪里來?

“從哪里來”這個參數很重要,因為它給咱們開發、調試提供了極大的便利。試想下,在Action路由表中,咱們能夠很清晰地看出一個Action將會到哪個Service處理,但沒法直觀地看出一個Action是從哪里觸發的,而且同樣的Action可能由不同的組件觸發,這是沒法從Action路由表中直觀看出來的。

所以,咱們給Rebus增加了一個調試功能,只要打開這個功能,便可以打印Action信息。

另外,如果一個Action被觸發,卻沒在路由表中找到這個Action的路由,Rebus會通過打印錯誤信息的方式提醒開發者。

自從Action有了源信息,領導再也不用擔心我找不到代碼的出處了,歐耶!

5 Rebus中的Action路由表

Action路由表這個概念在Flux與Redux中沒有,但也很好理解,就是一個很直觀的路由配置信息表。它是在Web應用開始初始化時,加載進來的。

在這張Action路由表中,你可以直觀地添加、修改、跟蹤一個Action會被哪個Service處理。當你希望某個Action被另一個Service處理時,直接在這個Action路由表中進行修改便是。

另外,在這個Action路由表中,咱們可以通過and()讓一個Action觸發多個service,如上圖的第29行。咱們寫了一個日志服務TodoLog.logAddTodo,希望系統處理ADD_TODO的同時也記錄這個事件。咱們就可以通過and()函數將這個服務綁定到ADD_TODO這條路由后面,and()的參數是一個數據,意思可以綁定多個服務。

但是,必須提醒的是,不建議and()中的服務也修改State,除非你肯定and()中的服務修改的State與Rebus.connet()中的服務修改的State的監聽者沒有任何交集。所以,再三提醒and()中只綁定跟State無關的服務,比如一些日志服務、系統統計服務等。

可能你會問,一個Web應用就一張Action路由表嗎?是的,也許在后續的版本中咱們可以支持多個Action路由表。但一張路由表也有它的好處——唯一性。比如你設置了某個Action的路由,結果另一個同事在另一張路由表中也設置了同名的Action路由,一開始獨立開發時可能沒有問題,一旦整合在一起,問題就出現了。所以,只有一張路由表是有好處的,大點沒關系。

6 Rebus中的組件

咱們都知道ReactJs的一大特征就是支持JSX語法,這使得JS代碼中可以直接寫“類標簽代碼”,而且一個組件能夠被嵌套在另一個組件中,并接受從上級組件傳遞進來的參數。

這種一層一層嵌套的寫法雖然很直觀,但也很蛋疼。就拿上面Redux實現的Header組件添加新Todo這個操作,執行的是傳遞進來的回調函數addTodo(…)。

這么做有幾個問題:

1)寫代碼時,到底是先約定Header組件要執行的回調函數叫addTodo,寫上級組件時按約定傳遞叫addTodo的參數?還是先寫好上級組件,根據上級組件傳遞的參數名來執行回調函數?到底是先有蛋還是先有雞?

2)果上級組件傳參時傳錯了,或者子組件寫回調函數時名稱寫錯了,如何跟蹤代碼,只知道光從代碼上看,我TM怎么知道這個回調函數是從哪個組件傳進來的?雖然現在有些工具能夠直接在瀏覽器上查看組件之間的嵌套關系,但那也是在應用能夠正常跑起來的情況才能Debug。

3)組件與組件之間的關系是通過硬編碼實現,如果現在有個子組件需要替換,可是這個子組件被嵌入在多個組件中,試問這得怎么找?

組件嵌套是ReactJs的一大亮點,但也是很多人認為ReactJs不適合做大型項目的原因。但我覺得這并不是ReactJs的問題,我們完全可以其他途徑解決上面這些問題。比如咱們的Rebus,組件與組件之間不會直接嵌套,而是跟調用后臺Service一樣,通過Rebus.execute()方法,發起一個Action。比如TodoApp這個上層組件,它嵌套了TodoHead/TodoBody/TodoFoot這三個子組件,但你會發現TodoApp組件是通過execute了三個分別叫GET_TODOHEAD、GET_TODOBODY、GET_TODOFOOT的Action來引入三個子組件,具體引入是怎么的組件,它并不關心。

Rebus總線根據Action路由表(rebus.route.js),分別找到這三個Action對應實現者(在這里咱們通過一個“組件工廠”CompFactory來響應這些Action)。當我們需要替換組件時,只需要在Action路由表中做出修改便是。

換句話說,在Rebus總線面前,每個組件都是平等的。組件只會跟Rebus總線溝通,不會直接嵌入其它組件,也不會被嵌到其它組件中。“組件樹”這個概念在Rebus是通過Action消息來實現的,是一種“動態嵌套”關系。

7 Rebus中的State

在Flux/Redux中,應用的各種狀態以一棵“狀態樹”的形式都是從根組件上灌進去,所有子組件的狀態一律從這個根組件上繼承下來(不管組件樹的結構有多深)。這樣做的好處就是一旦某個狀態發生變化,React組件自動從上到下進行更新。

但是,這么做真的好嗎?并不是說一個應用就一棵狀態樹這個想法不好,我也贊同這種設計,因為狀態是Web應用中最重要但又非常容易混亂的信息,“唯一性”對狀態來說,非常重要。

可是如果所有子組件的狀態都是從根組件一層一層傳遞進來的話,至少會有兩個問題:

組件之間的耦合性高,難以并行開發:子組件的狀態是由父組件決定。那到底先寫父組件還是先寫子組件?

狀態變化后,難以跟蹤變化的組件:假設你的某個操作修改了某個狀態,但這個狀態的變化會導致哪些組件更新了?光從Store中是看不出的,也無法跟蹤,只能從根組件一層一層往下查,看看這個State被傳遞到哪個組件中。

在Rebus中,咱們同樣維系著一棵“狀態樹”,并在應用初始化的時就加載進來的。

但不同的是,組件的狀態不是從上級組件中傳遞進來,是通過Rebus獲得的,而且組件有權決定自己關心哪個State的變化。

這樣做有幾個好處:

方便并行開發:因為組件之間沒有太過的耦合性。狀態都是通過Rebus獲得的,大部分情況下都是直接返回狀態樹中的某個狀態,這樣的“淺處理”非常適用于復雜系統開發中。

方便單元測試:由于組件直接與狀態綁定(監聽),要對一個組件進行單元測試,直接修改這個組件綁定的狀態便是,即是沒有上級組件的存在,也不影響測試。

方便維護代碼: 從上面的代碼中可以清晰地看出某個組件監聽哪些狀態,但反過來,某個狀態被哪些組件監聽了?從組件的代碼中是沒法直觀看出來的。這個問題也不應該通過查閱代碼的形式來解決,而應該通過咱們的Rebus來解決。咱們可以給Rebus增加一個方法,打印每一個State的監聽者。如下圖:

現在咱們既可以清晰地看出一個組件監聽了哪些狀態,也能看出一個狀態被哪些組件監聽。這為代碼的調試與維護提供極大的方便。

另外,我們可以輕松地打印出某個時刻的狀態樹或具體某個狀態的值。

8 總結

先給有耐心看到這里的人鼓個掌……然后也給我自己鼓個掌……因為對于一個拖延癥極度病患者來說,用業余時間寫這么一篇技術貼真心不容易。當我寫這句話的時候,距離這個帖子的第一句話,整整隔了一個月!——大哥,你是一禪指敲鍵盤的嗎?

言歸正傳,總結下咱們這個Rebus框架的特點:

實現了單向數據流模式,邏輯層次結構淺,思路清晰。

React組件職責單一,只負責渲染與響應交互。

以路由表的形式控制Action數據的流向,直觀、易維護。

React組件之間通過消息的形式實現動態嵌套。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78606.html

相關文章

  • 面試愛奇藝,竟然掛在第5輪……

    摘要:二面休息過后,就來了第二位面試官,面我運維的,運開嘛,如果沒有運維知識肯定是不行的。后來的對話中,面試官也表示,可能之前做的更多的是的工作,對于容器這塊不熟悉關系也不是很大。整個三面大概也持續了要有不到一個小時。 今天給大家分享我曾經在愛奇藝的面試,過程還是比較有意思的,可以給大家一些參考 聊騷階段 嗲妹妹:你好,我是愛奇藝的HR,我們正在招聘運維開發崗位,請問您最近有在看工作機會嗎...

    Magicer 評論0 收藏0
  • React 328道最全面試題(持續更新)

    摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅持每天花分鐘來學習與思考。 今天的React題沒有太多的故事…… 半個月前出了248個Vue的知識點,受到很多朋友的關注,都強烈要求再出多些React相前的面試題,受到大家的邀請,我又找了20多個React的使用者,他們給出了328道React的面試題,由我整理好發給大家,同時發布在了前端面試每日3+1的React專題,希望對大家有所幫助,同時大...

    kumfo 評論0 收藏0
  • 和小姐姐面試python,是種什么體驗?

    摘要:后來的對話中,面試官也表示,可能之前做的更多的是的工作,對于容器這塊不熟悉關系也不是很大。 showImg(https://segmentfault.com/img/remote/1460000018525265?w=1718&h=808); 這次給大家講講我2年前去愛奇藝面試高級運維開發崗位的經歷,希望對大家帶來一些幫助。 公眾號「Python專欄」后臺回復:自動化運維平臺,獲取整套...

    novo 評論0 收藏0
  • React為什么需Flux-like的庫

    摘要:的關鍵構成梳理了一下,需要配合的庫去使用,是因為要解決通信問題。還有各個事件之間,有可能存在依賴關系,事件后,也觸發。相比于傳統的事件系統,融入了不少的思想。中,將會是最大的門檻之一。 從學習React到現在的一點感受 我覺得應該有不少同學和我一樣,上來學React,覺得甚是驚艷,看著看著,發現facebook 安利了一個flux,圖畫的巨復雜,然后各種例子都有用這個東西,沒辦法,硬著...

    wangtdgoodluck 評論0 收藏0
  • 深入redux技術棧

    摘要:另外,內置的函數在經過一系列校驗后,觸發,之后被更改,之后依次調用監聽,完成整個狀態樹的更新。總而言之,遵守這套規范并不是強制性的,但是項目一旦稍微復雜一些,這樣做的好處就可以充分彰顯出來。 這一篇是接上一篇react進階漫談的第二篇,這一篇主要分析redux的思想和應用,同樣參考了網絡上的大量資料,但代碼同樣都是自己嘗試實踐所得,在這里分享出來,僅供一起學習(上一篇地址:個人博客/s...

    imingyu 評論0 收藏0

發表評論

0條評論

李世贊

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<