I am not able to see the intermediate results for sorting

I am making a sorting algorithm visualizer using JS, HTML and CSS and for showing the bubble sort I have written the following code

for (let i = 0; i < elements; i++) {
  for (let j = 0; j < elements; j++) {

    let a = temp[i].style.height;
    let b = temp[j].style.height;

    //this is to show the current elements begin compared
    temp[i].style.backgroundColor = 'green';
    temp[j].style.backgroundColor = 'blue';

    if (parseFloat(a) < parseFloat(b)) {

      //if the elements need to be swapped then the following code will change its height
      let t = a;
      temp[i].style.height = b;
      temp[j].style.height = t;


    }

    //this is to slow down the process                    
    sleep(500);

    //this is to change back the div's background to normal
    temp[i].style.backgroundColor = 'white';
    temp[j].style.backgroundColor = 'white';

  }
}
}

function sleep(num) {
  var now = new Date();
  var stop = now.getTime() + num;
  while (true) {
    now = new Date();
    if (now.getTime() > stop) return;
  }
}

but here the problem is that I am not able to see any intermediate results like seeing two divs being colored and changing height. I am only able to see the whole thing sorted when the sorting is done So what is the problem here ? How to solve this ?

Answer

While your code is running, the UI is not updating (there won’t be any rendering, otherwise webpages would flicker if they would have dynamic content being updated by JavaScript!), so your busy waiting will do nothing other than wasting CPU cycles.

Make the whole thing asynchronous and wait using a timeout: const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) will give you an async function that sleeps for the given amount of time, and then you can make your code an async function (so you can use await) and use await sleep(500) instead of sleep(500).

Since the code is now no longer synchronous, it won’t block the event loop, and will allow the UI to update while you are waiting.

Here is a working example of asynchronous waiting:

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const counter = document.getElementById('counter')
const countButton = document.getElementById('count-button')

async function count () {
  countButton.disabled = true
  
  counter.innerText = 'One...'
  await sleep(1000)
  counter.innerText = 'Two...'
  await sleep(1000)
  counter.innerText = 'Three...'
  await sleep(1000)
  counter.innerText = 'Done!'
  
  countButton.disabled = false
}

countButton.addEventListener('click', () => {
  // It's important to catch any asynchronous error here so it can be handled
  // regardless of where it happens in the process - otherwise it will become
  // an unhandled promise rejection.
  count().catch(e => console.error('An error occured during counting!', e))
})
<h1 id="counter">...</h1>
<button id="count-button">Count!</button>