I'm using xsate on a Node.JS backend. Here is the current flow :
Here is some pseudo code
const state = db.fetch(flowId) ?? machine.initialState;
// Use State.create() to restore state from a plain object
const previousState = State.create<DefaultContext, MyEvent>(stateDefinition);
// Use machine.resolveState() to resolve the state definition to a new State instance relative to the machine
const resolvedState = machine.resolveState(previousState);
const interpreter = interpret(machine).start(resolvedState);
onst newState: State<DefaultContext, MyEvent, any, Typestate<DefaultContext>> = interpreter.send(event);
db.saveState(flowId, newState);
My question is : Is it possible to Invoke a Promise ?
I would like to keep my FSM "alive" if I have pending promises. The goal is to modify the context based on the promise result. Is there some hook I could use ?
Thanks for any advise.
I have the same use case as you. So what I do is add an extra property to context, say waitingAsync
. Set it to true
on the state entry, and set it to false
on done.
Follow the Invoking Promises example with some modifications:
// ...
loading: {
// set waitingAsync to true
entry: assign((context) => ({...context, waitingAsync: true})),
invoke: {
id: 'getUser',
src: (context, event) => fetchUser(context.userId),
onDone: {
target: 'success',
actions: [
assign({ user: (context, event) => event.data })
// set waitingAsync to false
assign((context) => ({...context, waitingAsync: false}))
]
},
}
},
// ...
Then you can use the waitFor helper to wait until the promise is done.
const interpreter = interpret(machine).start();
interpreter.send(event);
await waitFor(interpreter, (state) => !state.context.waitingAsync);