什么是有限狀態(tài)機?

大家好,我是IT修真院北京總院第24期的學(xué)員,一枚正直純潔善良的web程序員

今天給大家分享一下,修真院官網(wǎng)js任務(wù)3,深度思考中的知識點——什么是有限狀態(tài)機??

1.背景介紹

什么是有限狀態(tài)機?

有限狀態(tài)機,(英語:Finite-state machine, FSM),又稱有限狀態(tài)自動機,簡稱狀態(tài)機,是表示有限個狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動作等行為的數(shù)學(xué)模型。


有限狀態(tài)機一般都有以下特點:

(1)可以用狀態(tài)來描述事物,并且任一時刻,事物總是處于一種狀態(tài);

(2)事物擁有的狀態(tài)總數(shù)是有限的;

(3)通過觸發(fā)事物的某些行為,可以導(dǎo)致事物從一種狀態(tài)過渡到另一種狀態(tài);

(4)事物狀態(tài)變化是有規(guī)則的,A狀態(tài)可以變換到B,B可以變換到C,A卻不一定能變換到C;

(5)同一種行為,可以將事物從多種狀態(tài)變成同種狀態(tài),但是不能從同種狀態(tài)變成多種狀態(tài)。

2.知識剖析

在js中,新建一個對象,用這個對象的屬性來模擬元素的狀態(tài),用這個對象的方法模擬元素在不同狀態(tài)的轉(zhuǎn)變,那么這個對象就是一個有限狀態(tài)機。

是否可用有限狀態(tài)機來描述,卻決于:

當(dāng)前狀態(tài)確定,有限個狀態(tài),響應(yīng)事件,在不同狀態(tài)間有規(guī)律的轉(zhuǎn)變。

它對JavaScript的意義在于,很多對象可以寫成有限狀態(tài)機。
舉例來說,網(wǎng)頁上有一個菜單元素。鼠標(biāo)懸停的時候,菜單顯示;鼠標(biāo)移開的時候,菜單隱藏。如果使用有限狀態(tài)機描述,就是這個菜單只有兩種狀態(tài)(顯示和隱藏),鼠標(biāo)會引發(fā)狀態(tài)轉(zhuǎn)變。

var menu = {

// 當(dāng)前狀態(tài)

currentState: 'hide',

// 綁定事件

initialize: function() {

var self = this;

self.on("hover", self.transition);

},

// 狀態(tài)轉(zhuǎn)換

transition: function(event){

switch(this.currentState) {

case "hide":

this.currentState = 'show';

doSomething();

break;

case "show":

this.currentState = 'hide';

doSomething();

break;

default:

console.log('Invalid State!');

break;

}

}

};

可以看到,有限狀態(tài)機的寫法,邏輯清晰,表達力強,有利于封裝事件。一個對象的狀態(tài)越多、發(fā)生的事件越多,就越適合采用有限狀態(tài)機的寫法。

另外,JavaScript語言是一種異步操作特別多的語言,常用的解決方法是指定回調(diào)函數(shù),但這樣會造成代碼結(jié)構(gòu)混亂、難以測試和除錯等問題。有限狀態(tài)機提供了更好的辦法:把異步操作與對象的狀態(tài)改變掛鉤,當(dāng)異步操作結(jié)束的時候,發(fā)生相應(yīng)的狀態(tài)改變,由此再觸發(fā)其他操作。這要比回調(diào)函數(shù)、事件監(jiān)聽、發(fā)布/訂閱等解決方案,在邏輯上更合理,更易于降低代碼的復(fù)雜度。

3.常見問題

有限狀態(tài)機有哪些應(yīng)用場景?

4.解決方案

滿足3點即可用:所需狀態(tài)確定,有事件觸發(fā)轉(zhuǎn)變狀態(tài),總狀態(tài)有限且轉(zhuǎn)變有規(guī)律。

頁面可用有限狀態(tài)機的元素較多且有規(guī)律時可用:例如:開關(guān)按鈕,下拉菜單,


Javascript Finite State Machine 函數(shù)庫

javascript-state-machine插件


//交通信號燈的模型描述:

var fsm = StateMachine.create({

initial: 'green',

events: [

{ name: 'warn',? from: 'green',? to: 'yellow' },

{ name: 'stop', from: 'yellow', to: 'red' },

{ name: 'ready',? from: 'red',? ? to: 'yellow' },

{ name: 'go', from: 'yellow', to: 'green' }

],

callbacks:{

callback1:function(){...},

callback2:function(){...},

...

},

error: function(){...}

});

initial選項用來表示fsm對象的初始狀態(tài),events選項用來描述fsm對象所有狀態(tài)的變化規(guī)則,每一種變化規(guī)則對應(yīng)一種行為。create方法為實例的每一種行為都添加了一個方法,調(diào)用這個方法就相當(dāng)于觸發(fā)對象的某種行為,當(dāng)對象行為發(fā)生時,對象的狀態(tài)就可以發(fā)生變化。如以上例子創(chuàng)建的實例將擁有如下行為方法: fsm.warn() : 調(diào)用該方法,實例狀態(tài)將從'green'變?yōu)?yellow' fsm.stop() : 調(diào)用該方法,實例狀態(tài)將從'yellow'變?yōu)?red' fsm.ready() : 調(diào)用該方法,實例狀態(tài)將從'red'變?yōu)?yellow' fsm.go() : 調(diào)用該方法,實例狀態(tài)將從'yellow'變?yōu)?green'

這些方法是StateMachine根據(jù)create時配置的events規(guī)則自動創(chuàng)建的,方法名跟events規(guī)則里面的name屬性對應(yīng),events規(guī)則里面有幾個不重復(fù)的name,就會添加幾個行為方法。同時為了方便使用,它還添加了如下成員來判斷和控制實例的狀態(tài)和行為: fsm.current - 返回實例當(dāng)前的狀態(tài) fsm.is(state) - 如果傳入的state是實例當(dāng)前狀態(tài)就返回true fsm.can(eventName) - 如果傳入的eventName在實例當(dāng)前狀態(tài)能夠被觸發(fā)就返回true fsm.cannot(eventName) - 如果傳入的eventName在實例當(dāng)前狀態(tài)不能被觸發(fā)就返回true fsm.transitions() - 以數(shù)組的形式返回實例當(dāng)前狀態(tài)下能夠被觸發(fā)的行為列表

Javascript Finite State Machine允許為每個事件指定兩個回調(diào)函數(shù),以warn事件為例: onbeforewarn:在warn事件發(fā)生之前觸發(fā) onafterwarn(可簡寫成onwarn) :在warn事件發(fā)生之后觸發(fā)。 同時,它也允許為每個狀態(tài)指定兩個回調(diào)函數(shù),以green狀態(tài)為例: onleavegreen :在離開green狀態(tài)時觸發(fā) onentergreen(可簡寫成ongreen) :在進入green狀態(tài)時觸發(fā)。

假定warn事件使得狀態(tài)從green變?yōu)閥ellow,上面四類回調(diào)函數(shù)的發(fā)生順序為: onbeforewarn → onleavegreen → onenteryellow → onafterwarn。 還為所有的事件和狀態(tài)指定通用的回調(diào)函數(shù): onbeforeevent :任一事件發(fā)生之前觸發(fā) onleavestate :離開任一狀態(tài)時觸發(fā) onenterstate :進入任一狀態(tài)時觸發(fā) onafterevent :任一事件結(jié)束后觸發(fā)

以{ name: 'warn', from: 'green', to: 'yellow' }為例,這八個回調(diào)函數(shù)順序為: onbeforewarn onbeforeevent onleavegreen onleavestate onenteryellow onenterstate onafterwarn onafterevent

5.編碼實戰(zhàn)

demo1

demo2

6.擴展思考

有限狀態(tài)機通常在什么地方被用到?

大體上編程都是對現(xiàn)實的抽象,有效狀態(tài)機也不例外,當(dāng)邏輯里面有大量判斷需要轉(zhuǎn)換狀態(tài)時,有限狀態(tài)機就有用處了,本質(zhì)上其是用查表法來把處理邏輯獨立到表中,從而可以用通用的代碼去處理任意復(fù)雜的狀態(tài)轉(zhuǎn)換。 具體場景有狀態(tài)超多的詞法分析(要識別各種關(guān)鍵字,運算符等等),工控軟件中,有些機器的控制邏輯也可以用到,擴展開來,任何復(fù)雜狀態(tài)邏輯的處理都可以

7.參考文獻

百度百科

博客

《javascript高級程序設(shè)計》

博客園

github


視頻鏈接? ? ?密碼: 85w1

ppt鏈接

感謝大家觀看

今天的分享就到這里啦,歡迎大家點贊、轉(zhuǎn)發(fā)、留言、拍磚~

技能樹.IT修真院

“我們相信人人都可以成為一個工程師,現(xiàn)在開始,找個師兄,帶你入門,掌控自己學(xué)習(xí)的節(jié)奏,學(xué)習(xí)的路上不再迷?!?。

這里是技能樹.IT修真院,成千上萬的師兄在這里找到了自己的學(xué)習(xí)路線,學(xué)習(xí)透明化,成長可見化,師兄1對1免費指導(dǎo)??靵砼c我一起學(xué)習(xí)吧~

我的邀請碼:12361358,或者你可以直接點擊此鏈接:http://www.jnshu.com/login/1/12361358

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

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

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