It used to be even worse, with various tabs' event loops accidentally interacting with each other whenever a `alert()` was called.
When we were (slowly, painstakingly) making the Firefox UI compatible with multi-thread and multi-process, we hit this kind of issues all the time. One of the reasons we introduced Promise and async/await (née task/yield) in JavaScript was to give us a fighting chance to at least look at the code and understand where it could all break. And then we had to come up with the tools to actually debug these...