¿Por qué el objeto Promise bloquea la representación?

Estaba probando el objeto Promise y escribí un código que simula una tarea de larga ejecución que es sincrónica. Estaba comparando Promise y setTimeout - verviolí:

<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <h2>Promise vs setTimeout</h2>
    <div><button id="settimeout-test">setTimeout with slow running function</button></div>
    <div><button id="promise-test">Promise and slow running function</button></div>
    <div><button id="clear">Clear Results</button></div>
    <h5>Results</h5>
    <div id="result"></div>

    <script>
        const slow = function() {
            let nu = Date.now();
            while (Date.now() - nu < 1000) {}
        }
        const getSlowPromise = () => new Promise(resolve => {
                slow();
                resolve();
        });
        const resultsElement = document.getElementById('result')
        const log = (message) => {
            resultsElement.innerText += message;
        }  

        const settimeoutButton = document.getElementById('settimeout-test');
        settimeoutButton.addEventListener('click', () => {
            const now = Date.now();
            log(`\nsetTimeout test starts after ${Date.now() - now} ms`);
            setTimeout(() => {
                slow();
                log(`\nSlow function completes after ${Date.now() - now} ms`);
            }, 0);
            log(`\nEvent listener completes after ${Date.now() - now} ms`);
        });

        const promiseButton = document.getElementById('promise-test');
        promiseButton.addEventListener('click', () => {
            const now = Date.now();
            log(`\nsetTimeout test starts after ${Date.now() - now} ms`);
            getSlowPromise().then(res => log(`\nPromise completes after ${Date.now() - now} ms`));
            log(`\nevent listener completes after ${Date.now() - now} ms`);
        })

        const clear = () => resultsElement.innerText = '';
        const clearButton = document.getElementById('clear');
        clearButton.addEventListener('click', () => clear());

    </script>

  </body>

</html>

Pensé que Promise y setTimeout se comportarían de manera similar, agregarían el código a la cola de tareas y luego continuarían la ejecución. El orden de los resultados es el mismo, pero la promesa con una tarea de larga duración parece bloquear la representación hasta que se complete la tarea de larga duración. ¿Alguien puede explicar esto?

El ejemplo funciona mejor en Chrome.

Actualizar No estoy tratando de hacer que la tarea de ejecución larga se ejecute en paralelo, solo quiero entender por qué Promise y setTimeout se comportan de manera diferente en mi ejemplo. Pero si desea ejecutar la tarea en paralelo, entonces Web Workers / Worker threads es el camino a seguir, como sugiere Quentin.

Pero la respuesta a mi pregunta parece ser que los constructores de Promise están sincronizados, como Bergi escribe en un comentario. Aquí hay una @ más larexplicació

Respuestas a la pregunta(1)

Su respuesta a la pregunta