In a nutshell
Open a tab and the browser runs several processes: a browser process for the window, a sandboxed renderer process per site (so one site can't crash or read another), a GPU process, and a network service. Inside one renderer, the main thread runs one thing at a time. Synchronous code runs on the call stack; setTimeout queues a macrotask and a resolved promise queues a microtask. When the stack empties, the event loop drains every microtask first, may render a frame, then runs one task — so 'A, setTimeout(D), promise(C), B' prints A, B, C, D.