-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
immediate
does not callback in interpret
#69
Comments
What I think is happening here is this: When you call let service = interpret(machine, () => {
// later, service.machine.current; // loaded
});
// service.machine.current; // loading? I understand that this is not super intuitive. I don't love the |
immediate
and invoke
immediate
does not callback in interpret
@SirNavith Does this make sense now? |
Sorry for the late reply. import { createMachine, immediate, interpret, invoke, reduce, state, state as final, transition } from 'robot3';
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const machine = createMachine({
start: state(transition("rainbow", "red")),
red: state(immediate("orange")),
orange: state(immediate("yellow")),
yellow: state(immediate("green")),
green: state(immediate("blue")),
blue: state(immediate("indigo")),
indigo: state(immediate("violet")),
violet: state(immediate("end")),
end: state(transition("restart", "start")),
});
async function main() {
console.log(`state: ${machine.current}`);
const { send } = interpret(machine, service => {
console.log(`state: ${service.machine.current}`);
});
await wait(100);
send("rainbow");
await wait(100);
send("restart");
await wait(100);
send("rainbow");
}
main(); The state machine will cycle through all of the colors, but the callback in So, I've changed the title of this post to reflect that, because I think this is a bug.
Not to tell you how to manage your own project or anything but maybe you could make another issue for this where you describe what you've been thinking and maybe I could comment there? |
No problem @SirNavith, happy to have the discussion. What is it you are wanting to do with the temporary state in the interpret callback? Usually that callback is used to update the UI when the new state has settled. If you were to update the UI in this case it would immediately be updated again, the user would never see the temporary state. If the purpose is for logging there is Maybe there's another use-case that I haven't thought of, so let me know. |
The snippet in the original post shows a use case:
|
let service = interpret(machine, () => {
console.log(`state: ${service.machine.current}`);
});
console.log(service.machine.current); // "loading" |
Yes, you can check that on demand, but then you would have to poll for state changes instead of being "given" the value when it changes, which is the point of The main point is that I am limited in JS literacy so I cannot figure out how this bug affects |
Before changing Robot's code do you want to write up an example in a codepen of something that you think won't work? The service returned by You don't need to poll for the state change. What you do need to do is use the service returned by interpret() to draw the UI appropriate for the first time. After that any other state changes will go through the interpret callback. Like I said, if you want to create a codepen / codesandbox of what you think won't work I'd be happy to get it working for you. |
I'll be closing this issue now:
Thanks! |
Hello! I've been loving this library but I discovered some unexpected behavior with
immediate
(long post ahead).Original code snippet:
Expected:
state: ready
state: loading
state: loaded
What actually happens:
state: ready
state: loaded
The state machine never actually has the
loading
state when transitioned to from animmediate
state! All other kinds of transitions toloading
would actually haveloading
be the state rather than skipping over it (I've actually had to retitle and rewrite this post a few times because I keep misidentifying what the pattern / problem is with the interaction ofinvoke
andimmediate
).One implication here is that, if you are using this to render a UI, your application can't know from the state machine that that 1 second is spent in
loading
; it'll still show itsready
state. You would have to add a side effect (in theload
function) that reaches outside the state machine to inform the outside world that there is loading taking place.Without changing how
immediate
works (i.e. in the current version of the library), you can use a recipe like this to get my originally expected behavior (at least in this situation; I haven't tested it in the infinite other ways you could):However, this has problems like
wait
andimmediately
) to be written in userspaceimmediate
without any purpose (as far as I'm aware?)I think some solutions could be
immediate
works this way very explicitlyexport const immediately = next => invoke(() => wait(0), transition('done', next));
immediate
to work in some way based off of the function in 2.The text was updated successfully, but these errors were encountered: