SushiCode
SushiCode

Reputation: 97

Waiting for timeout to finish before executing next line of code

I am making a sorting algorithm visualizer. I have a part of my program where if you click the merge sort button, it highlights whatever two elements are being compared in red, wait 1000ms, then turn the element back to aquamarine when the comparison is done.

To make the program wait 1000ms, I use the below method. It works just fine in my implementation of bubbleSort but not in mergeSort for some reason:

await new Promise(r => setTimeout(r, 0.1));

I have a theory that this is because the pausing method I used only pauses the async function but not entirely sure if that is correct. What happens in practice is that once the program hits the await new Promise() line, it just goes back up to the while statement and executes from there instead of waiting the 1000ms, then executing the line that would've turned barA and barB back to aquamarine.

function mergeSort(unsortedArray, aux = [...unsortedArray], lowIndex = 0, highIndex = unsortedArray.length - 1) {
  console.log(unsortedArray);

  // Base case
  if (highIndex === lowIndex) return;

  // Get midIndex
  const midIndex = Math.floor((highIndex + lowIndex) / 2);

  // Recursively run left side and right side until base case reached.
  mergeSort(unsortedArray, aux, lowIndex, midIndex);
  mergeSort(unsortedArray, aux, midIndex + 1, highIndex);

  // Merge the left sides and right sides
  merge(unsortedArray, aux, lowIndex, midIndex, highIndex);
}

// Does the actual work of ordering list
async function merge(unsortedArray, aux, lowIndex, midIndex, highIndex) {
  let auxkey = lowIndex;
  let i = lowIndex;
  let j = midIndex + 1;

  // While there are elements in left/right sides, put element in auxillary array
  // then increment the indexes by 1.
  while (i <= midIndex && j <= highIndex) {
    let arrayBars = document.getElementsByClassName('bar');
    const barA = arrayBars[i].style; 
    const barB = arrayBars[j].style;
    barA.backgroundColor = "red";
    barB.backgroundColor = "red";

    if (unsortedArray[i] <= unsortedArray[j]) {
      aux[auxkey] = unsortedArray[i];
      auxkey++;
      i++;
    } else {
      aux[auxkey] = unsortedArray[j];
      auxkey++;
      j++;
    }

    await new Promise(r => setTimeout(r, 0.1));
    barA.backgroundColor = "aquamarine";
    barB.backgroundColor = "aquamarine";
  }
}

This is a somewhat tirmmed down version of my code. For a slightly more comprehensive one, see: https://jsfiddle.net/SushiCode/k0954yep/9/

Upvotes: 0

Views: 927

Answers (1)

Bergi
Bergi

Reputation: 665456

I have a theory that this is because the pausing method I used only pauses the async function but not entirely sure if that is correct.

Indeed. You need to mark the mergeSort function as async as well, so you can await the merge() as well as the two recursive mergeSort() calls.

async function mergeSort(unsortedArray, aux = [...unsortedArray], lowIndex = 0, highIndex = unsortedArray.length - 1) { /*
^^^^^ */
  if (highIndex === lowIndex) return;

  const midIndex = Math.floor((highIndex + lowIndex) / 2);

  await mergeSort(unsortedArray, aux, lowIndex, midIndex);
//^^^^^
  await mergeSort(unsortedArray, aux, midIndex + 1, highIndex);
//^^^^^

  await merge(unsortedArray, aux, lowIndex, midIndex, highIndex);
//^^^^^
}

Upvotes: 1

Related Questions