日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
前端:從狀態(tài)管理到有限狀態(tài)機的思考

 1. 狀態(tài)管理

在我們前端開發(fā)中,一定會接觸現(xiàn)在最熱門的幾大框架(Vue, React等等),在使用框架的過程中,我們一定會接觸某些狀態(tài)管理工具。

撫順縣網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、APP開發(fā)、成都響應式網(wǎng)站建設等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)公司于2013年開始到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設就選成都創(chuàng)新互聯(lián)公司

Vue我們會使用Vuex來管理全局狀態(tài), React會使用Redux來管理。

首先是不是,在問為什么?

在使用類似Vue,React框架時,我們一定會使用狀態(tài)管理嗎?這個答案是肯定的?;蛟S我不會主動去使用Vuex, Redux,但我們編寫每一個組件的時候就已經(jīng)在管理狀態(tài),Vuex, Redux只是更方便我們進行全局的狀態(tài)管理。

為什么一定會使用狀態(tài)管理?這是因為現(xiàn)代前端框架使用數(shù)據(jù)驅(qū)動視圖的形式來描述頁面。比如,Vue、 React組件會有一個自己內(nèi)部,外部的狀態(tài)來共同決定組件的如何顯示的,用戶與組件交互導致數(shù)據(jù)變更,進而改變視圖。

框架 內(nèi)部狀態(tài) 外部狀態(tài)
Vue data props
React state, useState props

所以我們所寫大部分業(yè)務邏輯,是在管理狀態(tài),框架會幫我們狀態(tài)映射成視圖,這可以說是很經(jīng)典的MVVM模式。

 
 
 
  1. View = ViewModel(Model); 
  2. // 視圖 =  狀態(tài) + 管理 
  3. 復制代碼 

2. 有限狀態(tài)機:計算機中一種用來進行對象行為建模的工具

其作用主要是描述對象在它的生命周期內(nèi)所經(jīng)歷的狀態(tài)序列,以及如何響應來自外界的各種事件。

我們來理解一下上面這段話。

  • 一種對象行為建模工具

    我們用來描述對象行為,狀態(tài)隨著時間轉(zhuǎn)變過渡行為的工具??梢阅M世界上大部分事物。

  • 生命周期

    我們通過抽象對象所經(jīng)歷的狀態(tài)序列,來確定對象一系列可能的生命周期和轉(zhuǎn)變。

  • 響應外界事件

    外界事件能夠影響對象內(nèi)部狀態(tài)。對象能夠?qū)ν獠渴录鞒鲰憫?/p>

狀態(tài)機有基本幾個要素:

  1. 當前所處狀態(tài)

    在各個時刻只處于一種狀態(tài)

  2. 狀態(tài)轉(zhuǎn)移函數(shù)

    在某種條件下,會從一種狀態(tài)轉(zhuǎn)移到另外一種狀態(tài)。

  3. 有限狀態(tài)序列

    擁有有限,可枚舉的狀態(tài)數(shù)

 上面這張圖所描述的狀態(tài)機,我們使用js對象來進行描述

 
 
 
  1. const stateTool = { 
  2.   // 當前狀態(tài) 
  3.   currentState: '1', 
  4.    
  5.   // 狀態(tài)轉(zhuǎn)變函數(shù) 
  6.   transition: (event) => { 
  7.   switch(event.type) { 
  8.       case '1': { 
  9.         this.currentState = event.status; 
  10.         doSomething1(); 
  11.         break; 
  12.       } 
  13.       case '2': { 
  14.         this.currentState = event.status; 
  15.         doSomething2(); 
  16.         break; 
  17.       } 
  18.       case '3': { 
  19.         this.currentState = event.status; 
  20.         doSomething3(); 
  21.         break; 
  22.       } 
  23.       default:  
  24.         console.log('Invalid State!'); 
  25.         break; 
  26.     } 
  27.   } 
  28. 復制代碼 

使用有限自動機是一種狀態(tài)管理的思考方式,我們可以列舉組件狀態(tài)列表,設計觸發(fā)狀態(tài)函數(shù)。通過外部或內(nèi)部交互行為,觸發(fā)函數(shù)改變狀態(tài),根據(jù)狀態(tài)改變視圖

3. Flux思想

Flux是什么?Flux是一個Facebook開發(fā)的、利用單向數(shù)據(jù)流實現(xiàn)的應用架構(gòu)

簡單說,F(xiàn)lux 是一種架構(gòu)思想,專門解決軟件的結(jié)構(gòu)問題??梢哉f他是有限狀態(tài)機的另外一種形式。

一個Flux管理分為4個狀態(tài):

  • View:視圖層

  • Action(動作):視圖層觸發(fā)的動作 or 行為

  • Dispatcher(派發(fā)器):收集觸發(fā)行為,進行統(tǒng)一管理,統(tǒng)一分發(fā)給store層。

  • Store(數(shù)據(jù)層):用來存放應用的狀態(tài),根據(jù)dispatcher觸發(fā)行為,就提醒Views要更新頁面

要是同學了解flux的的工作流程,那么很容易就發(fā)現(xiàn)這是一種工程化的狀態(tài)機。

  • 初始狀態(tài)

我們通過store 存放的是初始化狀態(tài),這種初始化狀態(tài)數(shù)據(jù)可以頁面初始化時設定 或 頁面加載時請求后端接口數(shù)據(jù),來初始化store數(shù)據(jù)。

通過store的初始化數(shù)據(jù),來構(gòu)建初始化的視圖層。

  • 狀態(tài)轉(zhuǎn)移事件

根據(jù)視圖層的行為會觸發(fā)action,我們通過統(tǒng)一的dispatcher來收集action, dispatcher將行為派發(fā)給store。

  • 狀態(tài)轉(zhuǎn)移函數(shù)

store通過判斷事件的類型 和 payload,來修改內(nèi)部存儲狀態(tài)。達到狀態(tài)轉(zhuǎn)移的目的,并統(tǒng)一提醒view層更新頁面;

4. 全局到局部的狀態(tài)管理

既然我們是通過數(shù)據(jù)狀態(tài)來管理視圖的,那么在設計初期我們就可以從有限的狀態(tài)轉(zhuǎn)移來思考業(yè)務邏輯。通過思考每個狀態(tài)對應的數(shù)據(jù),狀態(tài)轉(zhuǎn)移函數(shù),我們可以很清晰的羅列出數(shù)據(jù)更變邏輯。從數(shù)據(jù)去控制視圖也是現(xiàn)代前端所接觸到的MVVM模式。

一個大型應用,我們也會使用Vuex 或 Redux來進行一整個應用的管理。

在平時的業(yè)務中,我們會遇到一個痛點是:Vuex,Redux是一個全局狀態(tài)管理,但我們現(xiàn)在需要在局部需要一個局部狀態(tài)管理變更,只能使用 mutation 或 dispatch 去提交更改。

如果我們頻繁的更新狀態(tài),那么我們需要為每一個局部模塊編寫大量dispatch函數(shù)來間接修改全局狀態(tài)。隨著應用的擴充,dispatch文件會越來越臃腫。

那么我們是不是可以使用不同的狀態(tài)管理工具,來實現(xiàn)局部狀態(tài)的管理。在局部狀態(tài)更新完之后,再去用局部更新去更新全局呢?

注:但這也會有一個缺點,局部管理相對獨立。有些高度復用的提交函數(shù)需要放在全局狀態(tài)管理上

a. 框架原生組件狀態(tài)管理

React Hooks + React.createContext

React Hooks提供了useReducer + useContext + Context 可以實現(xiàn)一個小型的狀態(tài)管理

 
 
 
  1. // 以下代碼就實現(xiàn)了一個能夠穿透組件的狀態(tài)管理 
  2. import React, { useReducer, useContext } from 'react'; 
  3.  
  4. const reducer = (state = 0, { type, ...payload }) => { 
  5.   switch (type) { 
  6.     case 'add': 
  7.       return state + 1; 
  8.     case 'desc': 
  9.       return state - 1; 
  10.     default: 
  11.       return state; 
  12.   } 
  13.  
  14. const Context = React.createContext(); 
  15. const Parent = () => { 
  16.   const [state, dispatch] = useReducer(reducer, 0); 
  17.   return ( 
  18.     <> 
  19.        
  20.          
  21.        
  22.      
  23.   ) 
  24.  
  25. function Son() { 
  26.   return  
  27.  
  28. function Counter() { 
  29.   const { state, dispatch } = useContext(Context); 
  30.   return ( 
  31.     
     
  32.        dispatch({ type: 'desc' })}>- 
  33.       {state} 
  34.        dispatch({ type: 'add' })}>+ 
  35.     
 
  •   ) 
  • export default Parent; 
  • 復制代碼 
  • Vue響應式數(shù)據(jù) + vue.Provide/inject

    使用vue響應式系統(tǒng) + provide/inject API來實現(xiàn)一個具有穿透性的局部狀態(tài)管理

     
     
     
    1. // Parent.vue 
    2.  
    3.  
    4.  
    5.  
    6. 復制代碼 
     
     
     
    1. // Son.vue 
    2.  
    3.  
    4.  
    5. 復制代碼 
     
     
     
    1. // Counter.vue 
    2.  
    3.  
    4.  
    5. 復制代碼 

    b. 線性狀態(tài)管理:Xstate

    Xstate是一個很有趣的類似有限狀態(tài)機的狀態(tài)管理, Xstate 著重點在于 管理狀態(tài) ,通過 狀態(tài)轉(zhuǎn)換去維護數(shù)據(jù) 。

    我們來定義一個簡單的promise狀態(tài)機,使用官方提供的工具進行可視化

     
     
     
    1. import { Machine } from 'xstate'; 
    2.  
    3. // 創(chuàng)建狀態(tài)機 
    4. const promiseMachine = Machine({ 
    5.   id: 'promise', // 唯一id 
    6.   initial: 'pending', // 初始化狀態(tài) 
    7.   states: { // 狀態(tài)集合 
    8.     pending: { 
    9.       on: { 
    10.         RESOLVE: 'resolved', 
    11.         REJECT: 'rejected', 
    12.    } 
    13.     }, 
    14.     resolved: { 
    15.       type: 'final', 
    16.     }, 
    17.     rejected: { 
    18.       type: 'final' 
    19.     } 
    20.   } 
    21. }) 
    22. 復制代碼 

    注意:warning::狀態(tài)機不擁有狀態(tài),他只是定義狀態(tài)和定義狀態(tài)轉(zhuǎn)移

    Xstate有提供函數(shù)來實現(xiàn)狀態(tài)機服務,實現(xiàn)擁有狀態(tài)的實體

     
     
     
    1. import { interpret } from 'xstate' 
    2. const promiseService = interpret(promiseMachine).onTransition(state =>  
    3.   console.log(state.value) 
    4. ) // 創(chuàng)建服務,指定狀態(tài)轉(zhuǎn)移時回調(diào)函數(shù) 
    5. promiseService.start() // 啟動服務 
    6. promiseService.send('RESOLVE'); // 通知服務轉(zhuǎn)移狀態(tài),并執(zhí)行回調(diào)函數(shù) 
    7. 復制代碼 

    這樣子我們就實現(xiàn)了一個簡單的Promise狀態(tài)機。他有很多應用,可以結(jié)合Vue,結(jié)合React進行使用。更加深入的內(nèi)容就需要到官方文檔中自行探索了!

    就我個人的看法,狀態(tài)機思想非常適合狀態(tài)轉(zhuǎn)移相對線形的場景,在某些狀態(tài)多循環(huán)的場景轉(zhuǎn)移會相對復雜些

    c. 可響應式的狀態(tài)管理器:Mobx

    mobx是一種響應式的狀態(tài)管理,他所提倡的是拆分store做數(shù)據(jù)管理。這就很適合做局部的狀態(tài)管理,根據(jù)局部狀態(tài)管理來更新全局狀態(tài)。

    相同的,我們舉個例子

     
     
     
    1. import { action, autorun, observable } from 'mobx' 
    2. import { observer } from 'mobx-react' 
    3. import React from 'react' 
    4.  
    5. const appStore = observable({ // 建立store 
    6.   count: 0, 
    7.   age: 18, 
    8. }) 
    9.  
    10. // autorun 只會觀察依賴的相關數(shù)據(jù) 
    11. // 使用當appStore.age更新時,才會觸發(fā)該函數(shù) 
    12. autorun(() => { 
    13.   // doSomething(); 
    14.   console.log('autorun', appStore.age); 
    15. }) 
    16.  
    17. const Counter = observer(() => { 
    18.   const { count } = appStore; 
    19.   const onAdd = action(() => { // 使用action更新store數(shù)據(jù) 
    20.     appStore.count++; 
    21.   }) 
    22.   const onDesc = action(() => { 
    23.     appStore.count--; 
    24.   }) 
    25.   return ( 
    26.     
       
    27.       
    28.       {count} 
    29.       
    30.     
     
  •   ) 
  • }) 
  •  
  • export default Counter; 
  • 復制代碼 
  • 5. 總結(jié)

    現(xiàn)在前端主流使用數(shù)據(jù)驅(qū)動視圖的形式,來實現(xiàn)業(yè)務。希望給大家?guī)韮牲c啟發(fā)

    1. 用有限狀態(tài)機去思考某些線性狀態(tài)場景的數(shù)據(jù)管理。

    2. 在之前的業(yè)務開發(fā)的時候,就會出現(xiàn)一個痛點,應用全局狀態(tài)管理非常臃腫。

      在不斷功能迭代的過程中,需要做不同的狀態(tài)管理,雖然都是對同一份數(shù)據(jù)進行維護,但維護的方式不同,進行一次狀態(tài)更新就需要編寫一個不同的dispatch函數(shù)。隨著業(yè)務需求的增加,dispatch函數(shù)越來越多,難以管理和復用。

      思考如何解決這個問題的時,偶然看到了有限狀態(tài)機相關文章,思考到應用的功能模塊在某一個時刻是相互獨立的,我們在局部將數(shù)據(jù)進行更新,之后用一個全局函數(shù)對數(shù)據(jù)進行統(tǒng)一替換。

    注:本文為探索性質(zhì),使用原生組件進行局部管理不需要引入依賴。但使用第三方工具造成包體積大小的增加,是否會增加性能消耗有待討論


    網(wǎng)頁標題:前端:從狀態(tài)管理到有限狀態(tài)機的思考
    分享網(wǎng)址:http://www.5511xx.com/article/dhgoiho.html