javascripthtmlarraysasynchronousvisualizer

JavaScript code is running at the same time and not waiting


I am making a sorting visualizer in javascript. This is a example of one of sorting algorithms: selection sort But when I run the code even if the Selection sort visualizer.compare and visualizer.swap functions have 1 seconds pauses the array is sorted instantly instead of pausing. I think this is because javascript runs asynchrony beacuse if I instead make the code that swaps the heights of the bars into a timeout it runs like normal except after the timeout time has passed all of the heights are changed at the same time which is weird

all of the code is run by adding a on click event to a button that runs the selectionSort function when clicked (github code https://github.com/Jalrux/sorting-visualizer)

function selectionSort(array, visualizer) {
    let arrayLength = array.length;
    let minIndex;

    // loop through the array and sort each value array
    for (let i = 0; i < arrayLength; i++) { // loop through all indexes of array   
        minIndex = i; // assume that element with i index is minimum

        // Find the minimum element in unsorted array 
        for (let j = i + 1; j < arrayLength; j++) { // loop through indexes of unsorted elements
    
            visualizer.compare(i, j); // run the comparing visualizer
            if (array[minIndex] > array[j]) { // check if the element of minIndex is larger than value of the index j
                minIndex = j; // set minIndex to j
            }
        }

        visualizer.swap(minIndex, i); // run the swapping visualizer
        let temp = array[i]; // Swap the minimum element with element of index i 
        array[i] = array[minIndex];
        array[minIndex] = temp;
        
        visualizer.finished(i); // change the color of the bars at index minIndex to the finished color
    }
}

export {selectionSort, generateArray};

This is the code for the swap function in visualizer.js file

// change the colors of 2 bars to the swapping color and swap
export function swap(index1, index2) {
    let bar1Style = arrayBars()[index1].style;
    let bar2Style = arrayBars()[index2].style;

    // save the previous colors
    let bar1Color = bar1Style.backgroundColor;
    let bar2Color = bar2Style.backgroundColor;  
    
    // change the colors to the comparing color
    bar1Style.backgroundColor = swapColor;
    bar2Style.backgroundColor = swapColor;
    
    // swap the heights of the bars
    pause();
    let bar1height = bar1Style.height;
    let bar2height = bar2Style.height;
    bar1Style.height = bar2height;
    bar2Style.height = bar1height;
    pause(); 

    // change the colors back to their original colors
    bar1Style.backgroundColor = bar1Color;
    bar2Style.backgroundColor = bar2Color;
}


// some helper functions that are in the visualizer.js file
export function arrayBars() {
    return document.getElementsByClassName('array-bar');
}
// sleeps for pauseTime seconds 
export function pause() {
    setTimeout(function() {}, pauseTime);    
}

Solution

  • Maybe use a promise-based delay with async/await.

    function delay(time) {
      return new Promise(res => {
        setTimeout(() => res(), time);
      });
    }
    
    async function main() {
      console.log('First... waiting for two seconds');
      await delay(2000);
      console.log('Second... waiting for five seconds');
      await delay(5000);
      console.log('Done');
    }
    
    main();