Following on from my question Modifying the string in a text box pushes the cursor to the end and @jessta’s reply: “A Cmd msg returned from update is dispatched immediately before the call to view. In the case of a Cmd msg calling a port, the port will be called synchronously so the view won’t be updated at the time your JS is run.”
My question is:
What do we know about the Elm runtime timeline? What happens when?
- a message is fired
- update captures the message, chooses the appropriate branch, and executes the branch…
- at the end of the branch is
( update model, run command )
What can we say about this last part?
Does the instruction to update the model happen BEFORE the command is run?
If so, does it COMPLETE before the command is run?
So that values in the model are ready for use by anything that follows the command.
This is relevant in the case of a command that is pushing something through a port: if the model is updating an element to which the port-JavaScript needs access, then the model update must happen and complete first.
Do we therefore have the following timeline…
model is updated —> command is run —> (port JS is executed) —> view is updated
…reliably in that order?
@jessta continues, “The general solution to this is to delay the JS from running until the next animation frame which will be after the view
has been updated. You can do this in JS with setTimeout() or with requestAnimationFrame() called within the function you’ve subscribed to the port on the JS side.” And this is backed up by other replies which say to use requestAnimationFrame
.
Is this the way to ensure the view is updated before port JS is run, ie:
model is updated —> command is run —> (port JS is delayed til next frame) —> view is updated —> port JS is executed
Just for completeness, can we switch the end of an update branch around, so that the command runs and port JS is executed BEFORE the model is updated?
Finally, are there any other timing ‘issues’ an Elm programmer should be aware of?