赞
踩
大家好,小编为大家解答js状态栏显示信息怎么设置的问题。很多人还不知道javascript 状态机,现在让我们一起来看看吧!
状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
需求:
实现一个开关功能的电灯
代码实现:
- class Light {
- constructor() {
- this.state = 'off' // 默认关灯
- this.button = null
- }
- init() {
- const button = document.createElement('button')
- this.button = document.body.appendChild(button)
- this.button.innerHTML = '开关'
- this.button.onclick = () => {
- this.handleStateChange()
- }
- }
-
- handleStateChange() {
- if(this.state == 'off') {
- console.info("开灯")
- this.state = 'on'
- } else if(this.state == 'on') {
- console.info('关灯')
- this.state = 'off'
- }
- }
- }
-
- const light = new Light()
- light.init()

这个功能暂时告一段落Python中的所有运算符号。
但过不久产品经理要求实现这样一种电灯:第一次按下打开弱光,第二次按下打开强光,第三次才是关闭电灯。
你只得更改 handleStateChange 代码为
- handleStateChange () {
- if (this.state === 'off') {
- console.log('弱光')
- this.state = 'weakLight'
- } else if (this.state === 'weakLight') {
- console.log('强光')
- this.state = 'strongLight'
- } else if (this.state === 'strongLight') {
- console.log('关灯')
- this.state = 'off'
- }
- }
功能是实现了,但存在如下问题:
封装一般是封装对象的行为,而不是封装对象的状态,但是在状态模式中,关键的就是把每种状态封装成单独的类,跟状态相关的行为都封装在类的内部
首先先拆解出该电灯存在三种状态:OffLightState (关灯)、WeakLightState (弱光)、StrongLightState (强光)。
编写状态类如下:
- class OffLightState {
- construct (light) {
- this.light = light
- }
-
- handleStateChange () {
- console.log('弱光')
- this.light.setState(this.light.weakLightState)
- }
- }
-
- class WeakLightState {
- construct (light) {
- this.light = light
- }
-
- handleStateChange () {
- console.log('强光')
- this.light.setState(this.light.strongLightState)
- }
- }
-
- class StrongLightState {
- construct (light) {
- this.light = light
- }
-
- handleStateChange () {
- console.log('关灯')
- this.light.setState(this.light.offLightState)
- }
- }

编写 Light 类:
采用状态对象的形势标识当前的开关状态,而不是之前的字符串( ‘weakLight’、’strongLight‘、‘off’)
- class Light {
- construct () {
- this.offLightState = new OffLightState(this)
- this.weakLightState = new WeakLightState(this)
- this.strongLightState = new StrongLightState(this)
-
- this.currentState = this.offLightState // 初始化电灯状态
- this.button = null
- }
-
- init () {
- const button = document.createElement('button')
- this.button = document.body.appendChild(button)
- this.button.innerHTML = '开关'
-
- this.button.onclick = () => {
- this.currentState.handleStateChange()
- }
- }
-
- setState (newState) {
- this.currentState = newState
- }
- }
-
- const light = new Light()
- light.init()

有如下优点:
非面向对象实现的策略方式,将各个状态定义在一个对象里,通过对象映射的方式,以及 call 语法绑定主体类 Light
- const lightState = {
- 'offLight': {
- handleStateChange:function() {
- console.log('弱光')
- this.setState(lightState.weakLight)
- }
- },
- 'weakLight': {
- handleStateChange:function() {
- console.log('强光')
- this.setState(lightState.strongLight)
- }
- },
- 'strongLight': {
- handleStateChange:function() {
- console.log('关灯')
- this.setState(lightState.offLight)
- }
- }
- }
-
- class Light {
- constructor () {
- this.currentState = lightState.offLight // 初始化电灯状态
- this.button = null
- }
-
- init () {
- console.info(this,"this")
- const button = document.createElement('button')
- this.button = document.body.appendChild(button)
- this.button.innerHTML = '开关'
- this.button.onclick = () => {
- this.currentState.handleStateChange.call(this) // 通过 call 完成委托
- }
- }
-
- setState (newState) {
- this.currentState = newState
- }
- }
-
- const light = new Light()
- light.init()
-

比如实现个收藏,与取消收藏功能
- import StateMachine from 'java-state-machine'
- import $ from 'jquery'
- var fsm = new StateMachine({
- init: '收藏',
- transitions: [
- { name: 'doStore', from: '收藏', to: '取消收藏' },
- { name: 'deleteStore', from: '取消收藏', to: '收藏' }
- ],
- methods: {
- onDoStore: function () {
- console.log('收藏成功')
- updateText()
- },
- onDeleteStore: function () {
- console.log('取消收藏成功')
- updateText()
- }
- }
- })
- const updateText = function () {
- $('#btn1').text(fsm.state)
- }
-
- $('#btn1').on('click', function () {
- if (fsm.is('收藏')) {
- fsm.doStore()
- } else {
- fsm.deleteStore()
- }
- })
- // 初始化
- updateText()
-

promise 的 pending fulfilled rejected 是三个不同的状态,并且每种状态都有相应的行为
- import StateMachine from 'java-state-machine'
- var fsm = new StateMachine({
- init: 'pending',
- transitions: [
- { name: 'resolve', from: 'pending', to: 'fulfilled' },
- { name: 'reject', from: 'pending', to: 'rejected' }
- ],
- methods: {
- onResolve: function (state, data) {
- data.successCallBacks.forEach((fn) => fn())
- },
- onReject: function () {
- data.failCallBacks.forEach((fn) => fn())
- }
- }
- })
- class MyPromise {
- constructor(fn) {
- this.successCallBacks = []
- this.failCallBacks = []
- fn(
- () => {
- fsm.resolve(this)
- },
- () => {
- fsm.reject(this)
- }
- )
- }
- then(successCall, failCall) {
- this.successCallBacks.push(successCall)
- this.failCallBacks.push(failCall)
- }
- }
-
- const loadImg = function (src) {
- const promise = new MyPromise((resolve, reject) => {
- const img = document.createElement('img')
- img.onload = function () {
- resolve(img)
- }
- img.onerror = function (err) {
- reject(err)
- }
- img.src = src
- })
- return promise
- }
- var src = ' //www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
- let result = loadImg(src)
- result.then(function (img) {
- console.info('ok1')
- })
- result.then(function (img) {
- console.info('ok2')
- })
-

只是实现 promise 功能的一部分,但已足够说明状态模式的使用方式
相同点:
它们都有一个上下文、一些策略或者状态类,上下文把请 求委托给这些类来执行
不同点:
策略模式:各个策略类之间是平等又平行的,它们之间没有任何关系,所以客户必须熟知这些策略类的作用,以便客户自己可以随时主动切换算法。
状态模式:状态和状态对应的行为早已被封装好,状态之间的切换也早就被规定,“改变行为”这件事发生在状态模式的内部,对于客户来说,不需要了解这些细节。比如电灯的开与关,是由程序切换的,不用用户传入状态值。
你的点赞是对我最大的肯定,如果觉得有帮助,请留下你的赞赏,谢谢!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。