JavaScript FSM 簡單理解就是一種狀態(tài)機,是一種能夠在程序中相互轉換的抽象機器,能夠按照特定的規(guī)則自動運行。
舉個例子,像自動售貨機,當用戶投入硬幣,它會從接收硬幣狀態(tài)轉換到選擇商品狀態(tài),然后在用戶選擇商品后,又會從這個狀態(tài)轉換到支付狀態(tài),最后到出貨狀態(tài),這個整個自動售貨機的過程就是一個狀態(tài)轉移的過程。
在編寫代碼的時候,為了實現自動狀態(tài)轉移的過程,我們通常可以使用 if 和 switch 語句實現,但是在大型的程序中這種方式會很復雜,代碼很難閱讀和維護,這個時候 FSM 就可以發(fā)揮作用,把程序的流程轉化為狀態(tài)的轉移,降低代碼的復雜度,提高代碼的可讀性和可維護性。
// 簡單的狀態(tài)轉移 const machine = { 'start': ['processing'], 'processing': ['success', 'error'], 'success': [], 'error': [] }
在這個狀態(tài)轉移的過程中,我們首先定義狀態(tài)機的起始狀態(tài),然后再定義狀態(tài)之間的轉移過程,最后達到實現狀態(tài)轉移的功能。
在上面的代碼中,通過一個 JavaScript 對象來表示有限狀態(tài)機,如 start, processing, success, error 等,這些狀態(tài)之間的轉移過程通過狀態(tài)數組實現,比如 start 出發(fā)可以轉到 processing,processing 狀態(tài)對應的有 success 和 error 兩個狀態(tài),如果 processing 狀態(tài)下的代碼出現異常,則會轉移到 error 狀態(tài)。
在代碼中使用 FSM,可使代碼更加可觀,增加代碼的可讀性,并實現程序的精細控制和靈活調整,非常適合在復雜的程序中使用。
// 繼續(xù)舉例說明 const machine = { 'initState': { pressButton: function () { console.log('輸入金額...'); this.setState(this.moneyState); }, ejectMoney: function () { console.log('請先輸入金額...'); }, dispense: function () { console.log('請先輸入金額...'); } }, 'moneyState': { pressButton: function () { console.log('輸入金額...'); this.setState(this.moneyState); }, ejectMoney: function () { console.log('退錢成功...'); this.setState(this.initState); }, dispense: function () { // 處于購買狀態(tài) if(商品庫存>0){ console.log('售出商品'); 商品庫存--; 余額減少; if(余額>0){ this.setState(this.moneyState); }else{ this.setState(this.initState); } }else{ console.log('商品已售空...'); this.setState(this.initState); } } } }
在這個例子中我們定義了一個自動售貨機的有限狀態(tài)機 FSM,首先我們定義了兩個狀態(tài):initState 和 moneyState,其中 initSate 是初始狀態(tài),moneyState 是投幣狀態(tài),每個狀態(tài)下的行為對應這個狀態(tài)可能執(zhí)行的操作,比如輸入錢,退錢,購買商品等。
在 moneyState 時,我們定義了輸入金額行為,如果最后計算的金額大于購買商品的價格,則自動轉到投開狀態(tài),如果不足,則自動退款,同時還要檢查商品是否已經售空。
可以看到,在上述代碼中,我們通過狀態(tài)轉移的方式徹底解決了商品狀態(tài)的變換過程,避免了大量的 if 和 switch 語句,使代碼更加易讀和易懂。
總之,FSM 是非常適用于大型程序開發(fā)的編程思想和模型,通過狀態(tài)機的概念和轉移行為,自動化執(zhí)行更加精細和靈活,大大提高了代碼的可讀性和可維護性。