什么是有限狀態(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)機的寫法属韧,邏輯清晰,表達(dá)力強蛤吓,有利于封裝事件宵喂。一個對象的狀態(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) :在進(jìn)入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 :進(jìn)入任一狀態(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.參考文獻(xiàn)

百度百科

博客

《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)幽崩。快來與我一起學(xué)習(xí)吧~

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咨油,一起剝皮案震驚了整個濱河市役电,隨后出現(xiàn)的幾起案子宴霸,更是在濱河造成了極大的恐慌瓢谢,老刑警劉巖氓扛,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件采郎,死亡現(xiàn)場離奇詭異蒜埋,居然都是意外死亡整份,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門火俄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓜客,“玉大人,你說我怎么就攤上這事德迹⌒独” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵肌毅,是天一觀的道長筷转。 經(jīng)常有香客問我,道長悬而,這世上最難降的妖魔是什么呜舒? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮笨奠,結(jié)果婚禮上袭蝗,老公的妹妹穿的比我還像新娘。我一直安慰自己般婆,他們只是感情好到腥,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蔚袍,像睡著了一般乡范。 火紅的嫁衣襯著肌膚如雪瓶佳。 梳的紋絲不亂的頭發(fā)上索赏,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音精钮,去河邊找鬼幼东。 笑死脓杉,一個胖子當(dāng)著我的面吹牛蕉堰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诀拭,長吁一口氣:“原來是場噩夢啊……” “哼细卧!你這毒婦竟也來了翰苫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后滓技,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叠必,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年辟犀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布猾昆,位于F島的核電站贴见,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜黍图,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望切诀。 院中可真熱鬧,春花似錦倒庵、人聲如沸擎宝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽艰亮。三九已至者疤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叠赦,已是汗流浹背驹马。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留眯搭,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓业岁,卻偏偏與公主長得像鳞仙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子笔时,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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