1.背景介紹javascript
有限狀態機,(英語:Finite-state machine, FSM),又稱爲有限狀態自動機,簡稱狀態機,是一個數學模型。是一個抽象機器,在任什麼時候候均可以處於有限數量的狀態之一。響應某些外部輸入,FSM能夠從一個狀態轉換到另外一個狀態;從一種狀態到另外一種狀態的變化稱爲過渡。狀態機的行爲能夠在現代社會中的許多設備中觀察到,這些設備根據它們呈現的事件序列執行預約的一系列行爲。例如自動售貨機,當存放適當的硬幣組合時分配產品,當車輛等待時改變順序的交通燈等。前端
有限狀態機最初應用在數字系統的涉及,它對數字系統的設計具備十分重要的做用。有限狀態機是指輸出取決於過去輸入部分和當前輸入部分的時序邏輯電路。,除了輸入部分和輸出部分外,有限狀態機還含有一組具備「記憶」功能的寄存器,這些寄存器的功能是記憶有限狀態機的內部狀態,它們常被稱爲狀態寄存器。java
在有限狀態機中,狀態寄存器的的下一個狀態不只與輸入信號有關,並且還與該寄存器的當前狀態有關,所以有限狀態機又能夠認爲是組合邏輯和寄存器邏輯的一種組合。其中,寄存器邏輯的功能是存儲有限狀態機的內部狀態;而組合邏輯又能夠分爲次態邏輯和輸出邏輯兩部分,次態邏輯的功能是肯定有限狀態機的下一個狀態,輸出邏輯的功能是肯定有限狀態機的輸出。git
在咱們前端開發中,咱們能夠套用有限狀態機模型,將業務流程狀態化,劃分狀態和相應的觸發事件與動做,利用生 命週期事件進行控制與執行。github
一個能夠用狀態機模擬的簡單機制的例子---旋轉門。異步
常見的旋轉門是控制通往地鐵和遊樂園的遊樂設施的旋轉門。在腰部高度有三個旋轉臂,一個在入口處。最初狀態,手臂被鎖住了,阻止進入,防止顧客經過。將硬幣或代幣存放在旋轉門上的一個槽中,能夠打開手臂,讓一位顧客穿過。顧客經過後,手臂再次被鎖定,直到另外一枚硬幣被插入。做爲一個狀態機,旋轉門有兩種可能的狀態:鎖定和解鎖。有兩種可能的輸入影響其狀態:將硬幣放入槽(硬幣)並推進手臂(推)。在鎖定狀態下,推臂不起做用;不管輸入推送有多少次,它都處於鎖定狀態。投入一枚硬幣-也就是給機器一個硬幣輸入-將狀態從「鎖定」轉換爲「解鎖」。在解鎖狀態下,放入額外的硬幣不起做用;那就是增長硬幣輸入不會改變狀態。可是,一個推着手臂的顧客,將推送這個動做輸入,狀態就轉回到鎖定狀態。函數
旋轉門狀態機也能夠用稱爲狀態圖(上圖)的有向圖表示 。每一個狀態都由一個節點(圓圈)表示。邊(箭頭)顯示從一個狀態到另外一個狀態的轉換。每一個箭頭都標有觸發該轉換的輸入。不會致使狀態改變的輸入(例如在解鎖狀態下的硬幣輸入)由返回到原始狀態的圓形箭頭表示。從黑點到鎖定節點的箭頭表示這是初始狀態。動畫
2.知識剖析ui
2.1:有限狀態機有什麼特色spa
有限狀態機fsm通常有如下特色:
*)能夠用狀態來描述事物,而且任一時刻,事物老是處於一種狀態;
*)事物擁有的狀態總數是有限的;
*)經過觸發事物的某些行爲,能夠致使事物從一種狀態過渡到另外一種狀態;
*)同一種行爲,能夠將事物從多種狀態變成同種狀態,可是不能從同種狀態變成多種狀態。
2.2:有限狀態機的組成
2.2.一、狀態機由一組狀態和轉換組成例如:
need-to-insert-img
狀態:固體 、 液體 、 氣體。
轉換 :融化 、汽化 、 冷凝 、 凍結。
2.2.二、有限狀態機形式(有限狀態機長什麼樣)
一、須要的函數庫:javascript-state-machine插件。
二、生成實例,建立生命週期:
var fsm = new StateMachine({
init: 'solid',
transitions: [
{name: 'Melt', from: 'solid', to: 'liquid'},
{name: 'Vaporize', from: 'liquid', to: 'gas'},
{name: 'Condense', from: 'gas', to: 'liquid'},
{name: 'Freeze', from: 'liquid', to: 'solid'}
],
methods: {
onBeforeMelt: function() { / ... / },
onBeforeVaporize: function() { / ... / },
onBeforeCondense: function() { / ... / },
onBeforeFreeze: function() { / ... / },
onLeaveSolid: function() { / ... / },
onLeaveLiquid: function() { / ... / },
onLeaveGas: function() { / ... / },
onEnterLiquid: function() { / ... / },
onEnterGas: function() { / ... / },
onEnterSolid: function() { / ... / },
onAfterMelt: function() { / ... / },
onAfterVaporise: function() { / ... / },
onAfterCondense: function() { / ... / }
onAfterFreeze: function() { / ... / }
}
});
//方法調用
//1,自執行方法:
fsm.onMelt();
fsm.onVaporize();
fsm.onCondense();
fsm.onFreeze();
//一、觸發調用方式:
fsm.Melt();
fsm.Vaporize();
fsm.Condense();
fsm.Freeze();
HTML代碼:
有限狀態機包含如下基本內容:
一、初始狀態init:init選項用來表示fsm對象的初始狀態,
二、轉換規則transitions:transitions選項用來描述fsm對象全部狀態的變化規則,每一種變化規則對應一種行爲。
三、方法methods:methods方法爲實例的每一種行爲都添加了一個方法,調用這個方法就至關於觸發對象的某種行爲,當對象行爲發生時,對象的狀態就能夠發生變化。
如以上例子建立的實例將擁有以下行爲方法:
fsm.Melt() :調用該方法,實例狀態將從'solid'變爲'liquid'
fsm.Freeze() :調用該方法,實例狀態將從'liquid'變爲'solid'
fsm.Vaporize() :調用該方法,實例狀態將從'liquid'變爲'gas'
fsm.Condense() :調用該方法,實例狀態將從'gas'變爲'liquid'
2.2.三、有限狀態機的方法
Javascript Finite State Machine容許爲每一個事件指定兩個自定義方法,以Melt事件爲例:
onbeforeMelt:在warn事件發生以前觸發
onafterMelt:在warn事件發生以後觸發。
每一個狀態指定兩個自定義方法,以solid狀態爲例:
onleaveSolid:在離開solid狀態時觸發
onenterLiquid:在進入liquid狀態時觸發。
2.2.四、通用的生命週期事件
爲了在發生轉換時跟蹤或執行操做,有如下五個通用的生命週期事件:
// onBeforeTransition -在任何轉換以前觸發
// onLeaveState -離開任何狀態被觸發
// onTransition -在任何過渡期間被觸發
// onEnterState -進入任何狀態被觸發
// onAfterTransition -任何轉換後觸發
2.2.五、特定的轉換和狀態
除了通用事件以外,還可使用特定的轉換和狀態來觀察轉換:
// onBefore-在特定的轉換以前觸發
// onBefore-在特定的轉換以前觸發
// onAfter-在特定的TRANSITION後觸發
// onLeave-離開特定的狀態觸發
// onEnter-進入特定狀態觸發
// on-簡寫onAfter
// on-簡寫onEnter
2.2.六、輔助方法:
// fsm.is(s) -若是狀態s是當前狀態,則返回true
// fsm.can(t) -若是t從當前狀態發生轉換,則返回true
// fsm.cannot(t) -若是t從當前狀態不能發生轉換,則返回true
// fsm.transitions() -返回當前狀態容許的轉換列表
// fsm.allTransitions() -返回全部可能的轉換的列表
// fsm.allStates() -返回全部可能狀態的列表
//Cancelling a Transition取消轉換
2.2.七、能夠經過false在如下任何生命週期事件中顯式返回來取消轉換
在方法中return false能夠取消當前觸發的行爲:
// onBeforeTransition
// onBefore
// onLeaveState
// onLeave
// onTransition
//全部隨後的生命週期事件將被取消,狀態將保持不變。
3.常見問題
如何使用有限狀態機
4 解決方案
首先建立fsm實例----設置初始初始狀態------規定轉換規則------定義方法。
var fsm = new StateMachine({ //建立fsm實例
init: 'solid', //設置初始狀態
transitions: [ //定義裝換規則
{name: 'Melt', from: 'solid', to: 'liquid'},
{name: 'Vaporize', from: 'liquid', to: 'gas'},
{name: 'Condense', from: 'gas', to: 'liquid'},
{name: 'Freeze', from: 'liquid', to: 'solid'}
],
methods: { //定義方法
onBeforeMelt: function() { / ... / },
onLeaveSolid: function() { / ... / },
onEnterLiquid: function() { / ... / },
onAfterMelt: function() { / ... / },
}
});
//觸發轉換
fsm.Melt();
fsm.Vaporize();
fsm.Condense();
fsm.Freeze();
6.擴展思考
Javascript Finite State Machine 的異步轉換
有時,咱們須要在狀態轉換期間執行一些異步代碼,並確保在代碼完成以前不會輸入新狀態。
舉個栗子:
當咱們從一個狀態轉換出來並想逐漸淡入一個UI組件,或者將它從屏幕上滑出來,並且不想在動畫完成以後轉換到下一個狀態。就能夠經過 從任何生命週期事件中返回Promise對象來實現此目的。從生命週期事件返回Promise將致使該轉換的生命週期暫停。能夠繼續解決,也能夠拒絕承諾。
7.參考文獻