nickfargo / state

Composable, heritable first-class states
statejs.org
Other
93 stars 8 forks source link

Events during transition states #7

Closed Nethken closed 10 years ago

Nethken commented 11 years ago

I'd like to have my transition states also be able to handle events, but trying

    transitions: {
        MyState: {
            origin: 'state0', target: 'state1',
            action: function () { /* async stuff here */ },
            events: {
                request: function() { /* add listeners for ongoing async stuff */ } 
           }
       }
    }

doesn't seem to have worked, the code never gets hit in the node debugger, and the request function does return a promise but in the testing code the returned value is undefined.

nickfargo commented 11 years ago

Including an action in a transition expression allows the Transitions generated from it to be asynchronous, wherein the Transition remains current until its end method is called, after which it will then proceed to its target state.

Therefore it is the expected responsibility of action either to call this.end() itself (synchronously), or to arrange for end() to be called later elsewhere (asynchronously).

So your example could work something like this:

var state = require('state');

var object = {};

state( object, {
  state0: state('initial'),
  state1: state,

  transitions: {
    MyTransitionState: {
      origin: 'state0', target: 'state1',
      action: function () {
        var transition = this;
        transition.emit('request');
        setTimeout( function () {
          transition.emit('request');
          transition.end();
        }, 100);
      },
      events: {
        request: function () {
          console.log("Emitted event 'request'");
        }
      }
    }
  }
});

object.state('-> state1');
// log <<< "Emitted event 'request'"
// >>> Transition

// ... 100 ms ...

// log <<< "Emitted event 'request'"