ECMA-262 never mentions an event loop. It defines jobs, and a host hook called HostEnqueuePromiseJob that the engine calls when a promise reaction is ready to run. When those jobs actually run, and what runs between them, is the host's business.
That's why setTimeout isn't in the language spec at all, and why arguing about whether a timer callback beats a .then callback can't be settled by reading ECMA-262 alone. The ordering everybody relies on, every promise job drained before the next timer task, comes from the HTML event loop and from Node, not from the core spec.
Still a useful split. Within one turn, promise reactions run in the order they were enqueued, and await on an already resolved value still waits for a job, so the code after it never runs synchronously. Dart has the same two-level shape, with work from scheduleMicrotask going ahead of queued events.
Hosts agree on more than they have to. I just wish fewer explanations started with a diagram the spec never drew.

