It looks to me like the case where this is required is actually screaming out for a new event type, not fixed dependency order. B shouldn't be listening for the same event as A is if B depends on A getting something done. A should be firing a new event which B can listen for.
The flaw with such a strategy is that it does not scale. (We used to do exactly what you described). In a big "eventful" app, you will have way too many events to keep track, and you will constantly be browsing trough different modules to understand the chain.
Lets assume the user clicks somewhere, so an event is fired "user-clicked-x" that model A listens to.
So you know that model B needs to change as well and you fire a new event type from model A, say "model-a-changed-because-of-user-clicked-x" or a more generic event, say "model-a-changed".
Both will cause headaches, because they require a quite high cognitive load. With the generic one, you have the issue that sometimes you want A to change but not B, which leads to lots of conditionals (all of which you need to remember).
With the specific one, you have two events that mean almost the same, but are different. With every model C and D you need to carefully evaluate which event you listen to.
In isolation, this is perfectly fine.But if you have 10+ of those things interacting with eachother, it will be a big mess. You will have 30-40 different events, that map out a hierarchical order that you need to track down through multiple modules every time you change something.
If you do not abstract the chain away, the complexity is simply too high. You'd have to keep roughly 15-20 links in your head, which is too much. With Flux or similar patterns, you just have to keep one pattern in your head.
In the end it's a simple story of abstraction. Your mind can only deal with a couple of different things. If you reach the threshold, you need to abstract. Flux shows one way to do this (and it is only useful if you've reached the need for abstraction threshold).
Having one or two short event chains is perfectly fine. If you have 5 different user interactions that have a complex ripple effect through the state of your app, you need to do something, or development speed slows.
This I can well believe, but I'm interested in this bit:
> you fire a new event type from model A, say "model-a-changed-because-of-user-clicked-x" or a more generic event, say "model-a-changed".
These two seem to be on opposite ends of a spectrum where I'd try to pick a middle point. I wouldn't want the semantics of "this is a reaction to a UI event" anywhere past the first event, it's way too detailed. I'd try to pick something like "model A's date field changed ", or ideally something more meaningful like "The User updated their address".
This still introduces a new link, which will overload your brain if you have too many of those.
To give you some context:
In the app I'm developing now, we've got roughtly 25 global user interactions (meaning an event that will be triggered with a DOM event).Most of these events affect more than one model. Quite a lot of those also trigger complex event chains.
Multiple models have complex dependencies that would form branched dependency chains with conditionals.
It's just impossible to have everything in your mind at all times, which you need to if you want to extend a chain without bugs.
Now you might not have this issue in your projects, because they don't require that kind of interactivity. If thats the case don't bother, keep doing what you are doing.
But if you ever realize that things get pretty complex in one of your projects, then you know where to start :).
At floobits we use "actions" in addition to model events for our flux like implementation. Views trigger usually actions, modifying models triggers events on the model. Views in themselves do not usually trigger model updates.
So think about opening up a file in a web editor, that's an action. Many things might care about when a file is opened. The tab UI, maybe a log, other users connected to your session. Sometimes views correlate well to model updates, like a form, but many times they do not in which case a different event type can be useful.
This makes sense. I've thought for a while that separating commands and events was the right thing to do, even if they use the same distribution mechanism.
That this works automatically and assures all events will be seen appropriately.
That is, now he just has to declare it in the interested party -- whereas in your case, the programmer will have to fully manually manage who gets what.
Is there some subtlety I've missed here?