大家好挺尾,我是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ù)庫
//交通信號燈的模型描述:
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)
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)
視頻鏈接? ? ?密碼: 85w1
感謝大家觀看
今天的分享就到這里啦湾笛,歡迎大家點贊、轉(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