Before you start reading this article, you should already be familiar with state machine lifecycle events.

Sometimes you need to execute some asynchronous code during state transitions and make sure you don’t enter a new state until the code is complete. A good example of this is when you leave a state and fade out a UI component, or slide it off the screen, and don’t want to move to the next state until the animation is complete

You can do this by returning a Promise object from any lifecycle event.

Returning a Promise from a lifecycle event causes the lifecycle of the transition action to pause. It can continue by resolving the Promise, or cancel the transition action by rejecting the Promise.

For example (using jQuery effects) :

  var fsm = new StateMachine({

    init: 'menu'.transitions: [{name: 'play'.from: 'menu'.to: 'game' },
      { name: 'quit'.from: 'game'.to: 'menu'}].methods: {

      onEnterMenu: function() {
        return new Promise(function(resolve, reject) {$('#menu').fadeIn('fast', resolve)
        })
      },

      onEnterGame: function() {
        return new Promise(function(resolve, reject) {$('#game').fadeIn('fast', resolve)
        })
      },

      onLeaveMenu: function() {
        return new Promise(function(resolve, reject) {$('#menu').fadeOut('fast', resolve)
        })
      },

      onLeaveGame: function() {
        return new Promise(function(resolve, reject) {$('#game').fadeOut('fast', resolve)
        })
      }
    }

  })
Copy the code

Make sure that promises are always resolved (or rejected), otherwise the state machine will be stuck in the undefined transition forever.