Does this mean that I cannot count on a callback that was .then evaluated before the callback will setTimeout to setTimeout in an otherwise synchronous control flow?
Yes, what does it mean; specification does not require implementations to work that way.
But in practice, the Promise enabled implementations that I tested planned then callback ("microtask" from the PendingJobs queue) immediately after the completion of the "macrotask" that scheduled it before other pending macros, even if the pending macros were scheduled before the microtask. ( setTimeout and events are macro-saved.)
For example, in those environments where I tested it, this gives reliable results A , C , B :
console.log("A"); setTimeout(_ => console.log("B"), 0); Promise.resolve().then(_ => console.log("C"));
But the JavaScript specification does not require this.
As Bergi notes, for user agent environments, the HTML5 specification covers this in its specifications for microcurrents and macro tasks. But this only applies to user agent environments (e.g., browsers).
For example, Node does not fulfill this specification specification (not least because its timer functions return objects, not numbers), but Node also gives us A , C , B above because (thanks to Benjamin Grunbaum!) It fulfills the promises with permission after nextTick but before any nextTick timer or I / O. See its essence for details.
Tj crowder
source share