jakesgordon / javascript-state-machine

A javascript finite state machine library
MIT License
8.69k stars 964 forks source link

Error "transition is invalid in current state" when returning promise from event of type "any" #175

Open beltschatsar opened 5 years ago

beltschatsar commented 5 years ago

I get error "​​transition is invalid in current state​​" when using a Promise in following "any" event:

Repro case:

import * as StateMachine from 'javascript-state-machine';

var fsm = new StateMachine({
  init: 'solid',
  transitions: [
        { name: 'melt', from: 'solid', to: 'liquid' },
        { name: 'freeze', from: 'liquid', to: 'solid' },
        { name: 'vaporize', from: 'liquid', to: 'gas' },
        { name: 'condense', from: 'gas', to: 'liquid' }
    ],
    methods: {
        onMelt: function () { console.log('I melted'); return new Promise((resolve, reject) => setTimeout(() => {console.log('onMelt'); resolve(true);}, 1000)); },
        onFreeze: function () { console.log('I froze') },
        onVaporize: function () { console.log('I vaporized') },
        onCondense: function () { console.log('I condensed') },
        onBeforeMelt: function () { return new Promise((resolve, reject) => setTimeout(() => {console.log('onBeforeMelt'); resolve(true);}, 1000)) },
        onLeaveSolid: function () { return new Promise((resolve, reject) => setTimeout(() => {console.log('onLeaveSolid'); resolve(true);}, 1000)) },
        // Following ​​Throws "transition is invalid in current state​​"
        onBeforeTransition: function () { return new Promise((resolve, reject) => setTimeout(() => {console.log('onBeforeTransition'); resolve(true);}, 1000)) },
        onLeaveState: function () { return new Promise((resolve, reject) => setTimeout(() => {console.log('onLeaveState'); resolve(true);}, 1000)) },
        onTransition: function () { return new Promise((resolve, reject) => setTimeout(() => {console.log('onTransition'); resolve(true);}, 1000)) },
    }
});

fsm.melt();

I would expect the output to be:

onBeforeTransition
​​​​​onBeforeMelt​​​​​
onLeaveState
​​​​​onLeaveSolid​​​​​
onTransition
I melted
​​​​​onMelt​​​​​

I got:

​​transition is invalid in current state​​
NelsonFrancisco commented 5 years ago

I would say this happens because:

As for the solution, I'm not sure. I cannot solve this problem too: When you return a promise in one of the initial state's methods, how do you resolve it?