I am trying to visualize a bubble sort algorithm, I am trying to figure out a way to make my for loop iterate once every 1000ms, so it steps through and I am able to draw the result of each iteration.
I have tried using setTimeout but the for loop continues to execute while the setTimeout executes asynchronously. Is there another way to just "step" through the for loop?
// bubble sort
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
delay();
}
}
}
return arr;
}
function delay() {
setTimeout(() => {
console.log('hello');
}, 1000);
}
You can convert your function to a generator function and yield the state of the array after each sort.
If you try to call .next().value
, when the outer-loop is finished, an exception will be thrown. This is where you can catch it and cancel the interval.
console.log('START');
let arr = [ 5, 3, 4, 2, 1 ],
gen = bubbleSort(arr),
wait = 1000,
counter = 0;
const intervalId = setInterval(() => {
try {
const value = gen.next().value.join(',');
console.log(`Step ${++counter}: ${value}`);
} catch (e) {
clearInterval(intervalId);
console.log('STOP');
}
}, wait);
function* bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
yield arr;
}
}
}
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
Alternatively, you can try adding a callback that starts a timeout that will return in a linear fashion.
let arr = [ 5, 3, 4, 2, 1 ], wait = 1000;
const stepFn = (step, arr) => {
const finalStep = Math.pow(arr.length, 2) - 1;
const result = arr.join(','); // Capture values
setTimeout(() => {
console.log(`Step ${step}: ${result}`); // Finally display them
if (step === finalStep) { console.log('STOP'); }
}, step * wait); // Asynchronous calls, but the timeout is linear
};
console.log('START');
bubbleSort(arr, stepFn);
function bubbleSort(arr, callback) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
callback(i * arr.length + j, arr); // Insert a callback
}
}
}
.as-console-wrapper { top: 0; max-height: 100% !important; }