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

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

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

1.背景介紹

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

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


有限狀態(tài)機(jī)一般都有以下特點(diǎn):

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

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

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

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

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

2.知識(shí)剖析

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

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

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

它對(duì)JavaScript的意義在于,很多對(duì)象可以寫(xiě)成有限狀態(tài)機(jī)。
舉例來(lái)說(shuō),網(wǎng)頁(yè)上有一個(gè)菜單元素。鼠標(biāo)懸停的時(shí)候,菜單顯示;鼠標(biāo)移開(kāi)的時(shí)候,菜單隱藏。如果使用有限狀態(tài)機(jī)描述,就是這個(gè)菜單只有兩種狀態(tài)(顯示和隱藏),鼠標(biāo)會(huì)引發(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)機(jī)的寫(xiě)法,邏輯清晰,表達(dá)力強(qiáng),有利于封裝事件。一個(gè)對(duì)象的狀態(tài)越多、發(fā)生的事件越多,就越適合采用有限狀態(tài)機(jī)的寫(xiě)法。

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

3.常見(jiàn)問(wèn)題

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

4.解決方案

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

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


Javascript Finite State Machine 函數(shù)庫(kù)

javascript-state-machine插件


//交通信號(hào)燈的模型描述:

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

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

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

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

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

5.編碼實(shí)戰(zhàn)

demo1

demo2

6.擴(kuò)展思考

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

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

7.參考文獻(xiàn)

百度百科

博客

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

博客園

github


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

ppt鏈接

感謝大家觀(guān)看

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

技能樹(shù).IT修真院

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

這里是技能樹(shù).IT修真院,成千上萬(wàn)的師兄在這里找到了自己的學(xué)習(xí)路線(xiàn),學(xué)習(xí)透明化,成長(zhǎng)可見(jiàn)化,師兄1對(duì)1免費(fèi)指導(dǎo)。快來(lái)與我一起學(xué)習(xí)吧~

我的邀請(qǐng)碼:12361358,或者你可以直接點(diǎn)擊此鏈接:http://www.jnshu.com/login/1/12361358

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,401評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,011評(píng)論 3 413
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,263評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,543評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,323評(píng)論 6 404
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,874評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,968評(píng)論 3 439
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,095評(píng)論 0 286
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,605評(píng)論 1 331
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,551評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,720評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,242評(píng)論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,961評(píng)論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,358評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,612評(píng)論 1 280
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,330評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,690評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容