有限状态机如何

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jnshu_it/article/details/84917211

这里是修真院前端小课堂,每篇分享文从

【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】

八个方面深度解析前端知识/技能,本篇分享的是:

【 有限状态机如何】

标题:

                               

【修真院web小课堂】有限状态机如何使用?

                               

开场语:

                               

大家好,我是IT修真院北京分院第36期的学员张新,一枚正直纯洁善良的web程序员,今天给大家分享一下,修真院官网js(职业)任务4,深度思考中的知识点——有限状态机如何使用

                               

(1)背景介绍:

                               

有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物。它 是一个数学模型。是一个抽象机器,在任何时候都可以处于有限数量的状态之一。响应某些外部输入, FSM可以从一个状态转换到另一个状态; 从一种状态到另一种状态的变化称为过渡。 状态机的行为可以在现代社会中的许多设备中观察到,这些设备根据它们呈现的事件序列执行预定的一系列行为。 例如自动售货机,当存放适当的硬币组合时分配产品,当车辆等待时改变顺序的交通灯等。 在我们前端开发中,我们可以套用有限状态机模型,将业务流程状态化,划分状态和相应的触发事件与动作,利用生命周期事件进行控制与执行

                               

(2)知识剖析:

我们来看一下阮一峰对有限状态机的描述

           它有三个特征:

            状态总数(state)是有限的。

            任一时刻,只处在一种状态之中。

            某种条件下,会从一种状态转变(transition)到另一种状态。

有限状态机一般都有以下特点:

            (1)可以用状态来描述事物,并且任一时刻,事物总是处于一种状态;

            (2)事物拥有的状态总数是有限的;

            (3)通过触发事物的某些行为,可以导致事物从一种状态过渡到另一种状态;

            (4)事物状态变化是有规则的,A状态可以变换到B,B可以变换到C,A却不一定能变换到C;

            (5)同一种行为,可以将事物从多种状态变成同种状态,但是不能从同种状态变成多种状态。

                       

(3)常见问题:

                               

有限状态机有如何应用在具体场景?

                               

(4)解决方案:

                               

  满足3点即可用:所需状态确定,有事件触发转变状态,总状态有限且转变有规律。


 

            页面可用有限状态机的元素较多且有规律时可用:例如:开关按钮,下拉菜单,

           

           

            还有任务中杀人游戏的玩家死活状态、白天黑夜状态等

                               

(5)编码实战:

                               

var fsm = new StateMachine({

    init: step,

    transitions: [

        { name: 'kill', from: 'live', to: 'deadSay' },

        { name: 'say', from: 'deadSay', to: 'playSay' },

        { name: 'disscus', from: 'playSay', to: 'voted' },

        { name: 'vote', from: 'voted', to: 'live' }

    ]

});

var status_init = {

    kill: false,

    say: false,

    disscus: false,

    vote: false

}

var progress = JSON.parse(sessionStorage.getItem("progress"));

if (!progress) {

    progress = status_init;

}

$(function () {

    if (progress.kill) {

        $("#killing").addClass("actived");

        for (var i = 0; i < data.length; i++) {

            if (data[i].kmode == "killer" && data[i].isdied == "true" && data[i].ktime == day) {

                var info = `<p>${data[i].number}号被杀手杀死,真实身份是${data[i].role}</p>`;

                $(".am").append(info);

            }

        }

    }

    if (progress.say) {

        $("#deadSay").addClass("actived");

    }

    if (progress.disscus) {

        $("#playSay").addClass("actived");

    }

    if (progress.vote) {

        $("#voted").addClass("actived");

    }

    $("#killing").click(function () {

        if (fsm.is('live')) {

            $("#killing").addClass("actived");

            fsm.kill();

            window.location.href = "task2-6.html";

            progress.kill = true;

            sessionStorage.setItem('progress', JSON.stringify(progress));

        }

        else {

            alert("请按照步骤来");

            console.log(fsm.state)

        }

    });

    $("#deadSay").click(function () {

        if (fsm.is('deadSay')) {

            $("#deadSay").addClass("actived");

            $('.mask').removeClass("hide");

            $('#txt').text("请死者亮明身份并发表遗言");

            $(".btns").children().click(function () {

                $(".mask").removeClass('db').addClass("hide");

            })

            fsm.say();

            progress.say = true;

            sessionStorage.setItem('progress', JSON.stringify(progress));

        }

        else {

            alert("请按照步骤来");

            console.log(fsm.state);

        }

    });

    $("#playSay").click(function () {

        if (fsm.is('playSay')) {

            $("#playSay").addClass("actived");

            $('.mask').removeClass("hide");

            $('#txt').text("请玩家依次发言");

            $(".btns").children().click(function () {

                $(".mask").removeClass('db').addClass("hide");

            })

            fsm.disscus();

            progress.disscus = true;

            sessionStorage.setItem('progress', JSON.stringify(progress));

        }

        else {

            alert("请按照步骤来");

        }

    });

    $("#voted").click(function () {

        if (fsm.is('voted')) {

            $("#voted").addClass("actived");

            fsm.vote();

            window.location = "task2-7.html";

            progress.vote = true;

            sessionStorage.setItem('progress', JSON.stringify(progress));

        }

        else {

            alert("请按照步骤来");

        }

    });

})

                               

(6)拓展思考:

                               

有限状态机主要应用在哪些方面?

                               

(7)参考文献:

                               

参考一:有限状态机库

参考二:js与有限状态机

参考三:阮一峰的有限状态机 

                               

(8)更多讨论:

                               

Q1:提问人:

1.有限状态机有哪些优点?

A1:回答人(可以是分享人,也可以是其他学员):

答:有限状态机的写法,逻辑清晰,表达力强,有利于封装事件。一个对象的状态越多、发生的事件越多,就越适合采用有限状态机的写法。

Q2:提问人:

2,为什么声明了有限状态机没有效果?

A2:回答人(可以是分享人,也可以是其他学员):

答:使用有限状态机的第一步是要引入有限状态机的js库,不然是无法使用的。

Q3:提问人:

3,可以用原生的js来模仿有限状态机吗?

A3:回答人(可以是分享人,也可以是其他学员):

答:可以,通过多个条件语句来触发事件和限制状态,不过推荐这种做法,这样会导致代码臃肿和难以维护。

                               

(9)鸣谢:

                               

感谢徐伟师兄,此教程是在他们之前技术分享的基础上完善而成。

                               

(10)结束语:

                               

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

PPT链接 视频链接

更多内容,可以加入IT交流群565734203与大家一起讨论交流

这里是技能树·IT修真院:https://www.jnshu.com,初学者转行到互联网的聚集地

猜你喜欢

转载自blog.csdn.net/jnshu_it/article/details/84917211