I can't remember of any concurrency issue arising from handling multiple messages from the view, to be honest. I don't know if there's a specific mechanism blocking them, but it's simply never happened in 3 years of building elm apps for a living.
You don't have any guarantees about when that will occur though. Updates and view rendering are run independently.
I have an application that tracks mouse movement using pointer events for the user to draw, and I've definitely had a message from that come through after my model has updated and I'm no longer on that screen (and so nothing in the view generated from the model should produce that message), so it definitely can happen, even if you haven't encountered it.
Even if you don't encounter it that way, there are a bunch of footguns using this approach (e.g: doing this with tasks, HTTP requests, anything that has a defined delay before the message comes back).
Note that this applies to any subscription and that it is effectively dropped forever; the next input event won't recover it (so in the case of resizing only the next resize event will change things, not the next input event). So e.g. you could have a long running operation in a Web Worker over ports and then if its result comes in right when your user happens to be inputting something then it is dropped and never returns.
The basic problem is that there is an undefined delay between a message is issued and when `update` is called on the message which can be caused by other messages being in the queue.
Here's an example with subscriptions and views.
Time 0: A subscription arrives with message `A` which is added to the message queue in Elm's runtime. Note that one "tick" in Elm's runtime has not yet passed so we don't process the queue just yet (to see why this can happen we can either look at Elm's source code or note that the fact that Elm doesn't lose a subscription even if updates are busy processing forces there to be a message queue of length > 1).
Time 1: Your view sends a message `B` which contains a snapshot of the model `M0` at Time 1. `B` is added to the message queue.
Time 2: Your update function pops off the message queue and processes `A`, resulting in a new model `M1`.
Time 3: The Elm runtime processes another tick and sees no new messages from either views or subscriptions.
Time 4: Since the runtime is now done examining subscriptions and view messages, your update function pops off the message queue and processes `B`, resetting the model back to `M0`.
At the end of this sequence you effectively haven't handled the subscription at all, and all this is on a single thread.
This can be improved by using coarse-grained actions like say `UpdatePerson(person)`. And this new `person` value can be obtained by the event handler itself when the user changes the name. However, the actual logic can sit inside a Person module, allowing us to do something like: `onChange=dispatch(UpdatePerson(Person.setFirstName(newName, currentPerson))`
This approach lets us keep the behaviour close to the view while encapsulating the actual implementation inside a rich domain model.
The view is generated in its own thread synced to the browser's rendering system. It is entirely possible for the model to have changed without the view having been updated yet to match.
If your model changes under your feet while you use this approach, it result in you silently overwriting that change with the old data.
You have a `numberOfOperations` field in your model that is incremented every time a message is processed and then check that your incoming new model has a `numberOfOperations` value that is exactly one larger than the current value. If not you then fire off a `Cmd` asking for a recomputation of the original message.
However, that can get pretty hairy pretty quickly (since you may not have a nice way of asking for recomputation) so I'm not sure if it ends up working out in the end.