新人第008天---初識(shí)flux

為了進(jìn)一步了解redux,提前了解flux是有必要的,因此,把這篇通俗易懂的文章翻譯一下,有助于自己以后理解。

A cartoon guide to Flux

圖解Flux

目前的web開(kāi)發(fā)界,flux是一個(gè)既流行又難懂的主題,因此,本文嘗試使用一種通俗易懂的方式來(lái)解釋其原理。

問(wèn)題

首先,需要解釋一下flux解決的基本問(wèn)題。flux是一種在應(yīng)用中處理數(shù)據(jù)的模式,與react共同誕生于Facebook并共同發(fā)展。盡管可以獨(dú)立使用,但很多開(kāi)發(fā)者都會(huì)選擇同時(shí)使用react和flux進(jìn)行開(kāi)發(fā)。它們最初是針對(duì)Facebook遇到的一系列問(wèn)題而開(kāi)發(fā)出來(lái)的。

在這一系列的問(wèn)題中,眾所周知的是Facebook的提示bug。當(dāng)用戶登錄Facebook時(shí),會(huì)發(fā)現(xiàn)消息圖標(biāo)上有一個(gè)消息提醒標(biāo)志。當(dāng)用戶點(diǎn)擊消息圖標(biāo)時(shí),卻發(fā)現(xiàn)根本沒(méi)有新消息,而提醒標(biāo)志也會(huì)隨之消失。幾分鐘后,如果用戶在站內(nèi)進(jìn)行了交互操作,那這個(gè)提醒標(biāo)志就會(huì)再一次出現(xiàn)。用戶又會(huì)再次點(diǎn)擊...還是沒(méi)有新消息。循環(huán)往復(fù),如入怪圈。

Facebook遇到的提示bug

不僅是用戶,F(xiàn)acebook的開(kāi)發(fā)團(tuán)隊(duì)更是對(duì)這個(gè)怪圈感到頭疼。bug總是在修復(fù)后不久又出現(xiàn)了。如此循環(huán)往復(fù),在bug與非bug中徘徊。

于是,F(xiàn)acebook開(kāi)始想法設(shè)法擺脫這個(gè)怪圈。他們的目標(biāo)不是僅僅單次修復(fù)bug,而是使整個(gè)系統(tǒng)更加可預(yù)測(cè),這樣他們才能確保這個(gè)問(wèn)題不會(huì)不停地出現(xiàn)。

根本問(wèn)題

根本問(wèn)題在于,數(shù)據(jù)在應(yīng)用中的流動(dòng)方式。

注釋:這是我從他們的談話分享的簡(jiǎn)化版本中收集到的信息??梢钥隙ǎ鎸?shí)使用的架構(gòu)一定有所不同。

模板把數(shù)據(jù)傳到view層

模板負(fù)責(zé)存儲(chǔ)數(shù)據(jù),同時(shí)將數(shù)據(jù)傳到view層中并對(duì)其進(jìn)行渲染。

由于用戶交互都通過(guò)視圖實(shí)現(xiàn),因此,視圖有時(shí)需要根據(jù)用戶輸入更新模板。而有時(shí),模板也需要更新其他的模板。

除此之外,這些動(dòng)作有時(shí)會(huì)觸發(fā)大量其他變化。我把這比作一場(chǎng)激動(dòng)人心的乒乓球比賽,你很難知道球會(huì)落在何地(變化在何時(shí)何處發(fā)生)

視圖更新模板。模板更新其他模板。這看上去真的向一場(chǎng)激動(dòng)人心的乒乓球比賽了。

當(dāng)然,這些變化還可能異步發(fā)生。一個(gè)變化可能就會(huì)出發(fā)多個(gè)其他變化。我想,這就像在乒乓球比賽中把一袋子乒乓球倒出來(lái),它們會(huì)飛得到處都是。

總之,這使得數(shù)據(jù)流debug變得十分困難。

解決方法:?jiǎn)蜗驍?shù)據(jù)流

Facebook決定使用一種不同的架構(gòu),使數(shù)據(jù)只向一個(gè)方向流動(dòng)-只有一個(gè)方向-每當(dāng)你插入新數(shù)據(jù),整個(gè)流程就會(huì)從頭開(kāi)始。他們把這種架構(gòu)叫做flux。

你可以在Facebook的flux文檔中找到這幅圖,它可以看上去酷多了。

它確實(shí)很酷,但是從上面這幅圖中可能看不出來(lái)。

一旦理解了flux,這幅圖就變得很清晰了。問(wèn)題是,如果你是flux小白,又直接看了文檔,那這幅圖就對(duì)你的理解沒(méi)什么幫助了(雖然它本來(lái)應(yīng)該幫助你理解的)。在開(kāi)始了解如何使用flux去做具體工作之前,這幅圖應(yīng)該幫助你對(duì)整個(gè)系統(tǒng)有個(gè)大體的了解。

而真正幫助我理解flux的不是像這樣的圖,而是對(duì)不同特征協(xié)同工作從而實(shí)現(xiàn)目標(biāo)的系統(tǒng)的思考。接下來(lái)我會(huì)向大家介紹這些特征。

結(jié)識(shí)特征

我首先簡(jiǎn)單介紹一下這些特征,然后再介紹他們是如何聯(lián)系在一起的。

動(dòng)作創(chuàng)建機(jī)(The action creator)

第一個(gè)特征就是動(dòng)作創(chuàng)建機(jī)。它負(fù)責(zé)創(chuàng)建動(dòng)作,這也是所有變更和交互實(shí)現(xiàn)的方法。每當(dāng)用戶想改變APP狀態(tài)或是渲染不同頁(yè)面,都會(huì)發(fā)射一個(gè)動(dòng)作。

動(dòng)作創(chuàng)建機(jī)像一個(gè)報(bào)務(wù)員,它負(fù)責(zé)為你格式化消息。

我認(rèn)為動(dòng)作創(chuàng)建機(jī)像一位報(bào)務(wù)員。你讓動(dòng)作創(chuàng)建機(jī)明白你需要發(fā)送什么信息,之后它就會(huì)用一種全系統(tǒng)可讀的方式將其進(jìn)行格式化。

動(dòng)作創(chuàng)建機(jī)通過(guò)類型(type)和負(fù)載(payload)來(lái)創(chuàng)建動(dòng)作。這個(gè)類型就是你在系統(tǒng)中的所定義的動(dòng)作類型(通常是一個(gè)常量列表)。比如:MESSAGE_CREATE 或 MESSAGE_READ。

使你的系統(tǒng)知道全部可能的動(dòng)作也有一定的副作用。一個(gè)新手開(kāi)發(fā)人員可以參與項(xiàng)目,打開(kāi)動(dòng)作創(chuàng)建機(jī)文件,看到整個(gè)系統(tǒng)提供的API-所有可能的狀態(tài)改變。

一旦動(dòng)作消息被創(chuàng)建,動(dòng)作創(chuàng)建機(jī)就會(huì)將動(dòng)作傳送給分發(fā)機(jī)。

分發(fā)機(jī)(The dispatcher)

分發(fā)機(jī)本質(zhì)上來(lái)說(shuō)是一個(gè)大回調(diào)注冊(cè)處。這有點(diǎn)像電話接線總機(jī)處的接線員。分發(fā)機(jī)存儲(chǔ)所有store,以便向這些store傳遞動(dòng)作。每當(dāng)一個(gè)動(dòng)作從動(dòng)作創(chuàng)建機(jī)被傳遞過(guò)來(lái),分發(fā)機(jī)就會(huì)將這個(gè)動(dòng)作傳給不同的store。

分發(fā)機(jī)就像一個(gè)電話接線員。它存儲(chǔ)著不同store的所有回調(diào)信息。

分發(fā)機(jī)通過(guò)同步的方式來(lái)進(jìn)行這樣的操作,這樣就可以幫助處理我之前提到的“多球乒乓比賽”效應(yīng)。如果你需要在不同store之間建立獨(dú)立性以便一個(gè)store可以在另一個(gè)之前進(jìn)行更新,那可以使用分發(fā)機(jī)來(lái)管理(通過(guò)waitFor()函數(shù))

flux的分發(fā)機(jī)與很多其他架構(gòu)的分發(fā)機(jī)不同。動(dòng)作都會(huì)被傳入注冊(cè)的store中,不管是什么類型。這就意味著,store不僅僅為某些動(dòng)作而設(shè)計(jì),而是會(huì)對(duì)所有的動(dòng)作進(jìn)行監(jiān)聽(tīng)并且對(duì)其進(jìn)行篩選,從中找出自己感興趣的部分。

store

接下來(lái)是store。store存儲(chǔ)著應(yīng)用中所有的狀態(tài),以及每個(gè)store中狀態(tài)的變更邏輯。

store像一個(gè)權(quán)力過(guò)度的官僚。所有的變更都必須經(jīng)過(guò)它。

我認(rèn)為store像一位權(quán)力過(guò)度的官僚。所有狀態(tài)變更必須要通過(guò)store。同時(shí),也無(wú)法直接向store請(qǐng)求改變狀態(tài),因?yàn)閟tore中沒(méi)有設(shè)值函數(shù)。要想改變狀態(tài),就必須遵循適當(dāng)?shù)牟襟E。。。即必須要通過(guò)動(dòng)作創(chuàng)建機(jī)/分發(fā)機(jī)途徑來(lái)提交動(dòng)作申請(qǐng)。

像我上述提到的,如果store通過(guò)分發(fā)機(jī)注冊(cè),所有的動(dòng)作都會(huì)被傳進(jìn)來(lái)。在store內(nèi)部通常有一個(gè)開(kāi)關(guān)語(yǔ)句來(lái)監(jiān)控動(dòng)作類型,以決定該store是否關(guān)心這一動(dòng)作。如果關(guān)心,該store就會(huì)指出需要據(jù)此動(dòng)作作出何種改變并且更新?tīng)顟B(tài)。

一旦store對(duì)state做了改變,它就會(huì)發(fā)射一個(gè)變更事件??刂埔晥D會(huì)被通知狀態(tài)已經(jīng)改變。

控制視圖和視圖(The controller view and the view)

視圖負(fù)責(zé)獲取狀態(tài),并且為用戶渲染頁(yè)面,同時(shí)也接受用戶的輸入信息。

控制視圖像一個(gè)中層管理者,從store處獲取通知,并向下級(jí)視圖傳遞數(shù)據(jù)。視圖向用戶展示數(shù)據(jù)。

視圖是一個(gè)展示者。它不知道整個(gè)應(yīng)用發(fā)生的事情,而只處理接受到的數(shù)據(jù)、將其轉(zhuǎn)換為用戶可理解的形式并進(jìn)行輸出(通過(guò)HTML)

控制視圖像store和視圖之間的中層管理者。store在狀態(tài)發(fā)生改變時(shí)告知控制視圖,而控制視圖則接受新的狀態(tài)并更新后的狀態(tài)傳遞給下級(jí)視圖。

他們?cè)鯓訁f(xié)同工作

現(xiàn)在,讓我們看一下這些特性是如何協(xié)同工作的吧。

安裝

首先需要安裝:應(yīng)用僅需要初始化一次。

1. store告知分發(fā)機(jī),每當(dāng)動(dòng)作發(fā)生時(shí),自己(store)都需要知道。

2. 接著,控制視圖向store請(qǐng)求最新的狀態(tài)。

3. store將狀態(tài)傳給控制視圖,控制視圖就將這個(gè)視圖順次傳遞給其子視圖去進(jìn)行渲染。

4. 當(dāng)狀態(tài)改變時(shí),控制視圖也會(huì)通知store。

數(shù)據(jù)流

安裝完成后,應(yīng)用就可以接受用戶輸入了。那就讓我們通過(guò)用戶做變更來(lái)觸發(fā)一個(gè)動(dòng)作。

我們通過(guò)用戶交互來(lái)講解數(shù)據(jù)流。

1. 視圖告知?jiǎng)幼鲃?chuàng)建機(jī)去準(zhǔn)備一個(gè)動(dòng)作。

第一步

2.動(dòng)作創(chuàng)建機(jī)創(chuàng)建動(dòng)作并將其傳到分發(fā)機(jī)中。

第二步

3. 分發(fā)機(jī)將動(dòng)作按序列傳給store。每個(gè)store都會(huì)知道所有的動(dòng)作。接著,store會(huì)挑出其感興趣的操作并依此來(lái)改變狀態(tài)。

第三步

4. 一旦狀態(tài)變更完成,store會(huì)通知相應(yīng)的視圖控制器。

5. 這些視圖控制器會(huì)向store請(qǐng)求更新后的狀態(tài)。

第四步和第五步

6. 當(dāng)獲取到狀態(tài)后,視圖控制器會(huì)告知其子視圖依據(jù)新?tīng)顟B(tài)進(jìn)行渲染。

這就是我對(duì)flux的所想所思。希望能幫到大家。



翻譯的不夠準(zhǔn)確,有些術(shù)語(yǔ)還需要查證,日后還會(huì)繼續(xù)更新。亟需批評(píng)指正~

未完待續(xù)。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容