狀態與資料流 非同步與人為操作下的狀態與資料流

Lin Yen-Cheng on 2017-03-06 6 min. read

資料流

UI 為顯示資訊的媒介,當然會和資料產生關係,這時就出現下面的情形:

  1. 資料的改變是否影響 UI 的呈現?
  2. UI 的操作是否影響資料的改變?

最天真的做法是直接在 Dom 中綁定資料,但這樣程式就必須每次都要去找 Dom 來改變資料 QQ

後來就出現了 Model(資料) 和 View(UI) 的概念,透過直接操作 Model 來影響 View,而 Model 和 View 之間的關係則由套件幫我們處理。

第一種 Model => View,就是俗稱的單向資料流(綁定) one-way data flow(binding)。常見的 React 以及 FLUX 就是這個概念,FLUX 就像是定義更明確的 MVC,在關注點分離的基礎上,讓資料流變得更多限制可預測。

另一種會互相影響的就是 Model <=> View ,也就是雙向資料流(綁定) two-way data flow(binding)。其中有個 MVVM 的設計模式,Model <=> ViewModel <=> View透過操作 ViewModel 來顯示 View 及改變 Model,像是  Vue.js 中的 v-model,舉例來說<input v-model="message">用 MVVM 來看就是 input <=> v-model <=> message

事件驅動

UI 同時也會受到使用者操作影響,加上 Javascript 是本身單執行緒的關係,資料也會因非同步(ajax, setTimeout)改變,操作加上非同步的變化,正確處理 Model 和 View 就變得越來越困難且複雜,舉登入搶票這個動作來說,拆解成底下四個步驟

  1. 按下 Login 按鍵
  2. 發出非同步請求
  3. 確認帳號資訊
  4. 搶票
  5. 進入搶票流程
  6. 完成搶票

若是在第五步完成前,使用者瞬間又按下了搶票,此時使用者是否算是成功呢?

有限狀態機

javascript-state-machine是一套實作狀態機的函式庫,透過觸發事件來做狀態的改變,而狀態改變的路徑是事先嚴格定義清楚的,像是我們透過發請求的事件來處發狀態從未登入移動到處理中

未登入 —–> 處理中 —–> 登入
OOO發請求OOO確認

加入了狀態的概念後,我們可以更快速的去理解剛剛的問題,最後也可以透過按登出按鍵的事件,來讓登入狀態回到未登入,使用起來的缺點是,狀態越定義越多時,畫出來的狀態遷移圖以及事件定義會變成世界奇觀,提個關鍵字 Redux-saga?

狀態管理

元件化的影響,當動態的資料越來越多時,Vuex 還有 Redux 就定義出了一個叫做 Store 的名詞,裡面用一般的物件儲存了目前的狀態,下面就是官網範例中存了 todos 的狀態,可以看出待辦一已完成,待辦二未完成

&#123;
  "todos": [
    &#123;
      "id": 0,
      "text": "待辦一",
      "completed": true
    &#125;,
    &#123;
      "id": 1,
      "text": "待辦二",
      "completed": false
    &#125;
  ]
&#125;

透過把狀態放在統一的位置外加受限制的資料流方向,提倡 single source of truth,所有的事件都只能特殊操作來改變 Store 裡的狀態,UI 也是依照特定的程序來依照 Store 來顯示,好像就簡單許多了 XD 但說實話懂概念跟實際上用在專案裡還是有一段距離…


喜歡這篇文章,請幫忙拍拍手喔 🤣

share