I am trying to set a timeout(wait time) between each call of drawLines()
inside a setTimeout()
in a while-loop.
while(i < j){
while(i < lastElIndex && array[i] < pivot){
const iCopy = i;
const lastCopy = lastElIndex;
i++;
const arrCopy = array.slice();
setTimeout(() => {
drawLines(arrCopy, iCopy, -1, lastCopy, -1);
});
}
while(j > firstElIndex && array[j] >= pivot){
const jCopy = j;
const firstCopy = firstElIndex;
j--;
const arrCopy = array.slice();
setTimeout(() => {
drawLines(arrCopy, -1, jCopy,-1, firstCopy);
});
}
I already tried setting the wait time like this
setTimeout(() => {drawLines(arrCopy, iCopy, -1, lastCopy, -1);}, 1000);
...but the timeout happens before the calling drawLines()
repeatedly without waiting between calls.
I also tried
setTimeout(async() => {
drawLines(arrCopy, iCopy, -1, lastCopy, -1);
await sleep(1000);
});
...with
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
...but nothing happened
Here is the whole function:
function quickSort(arr, firstElIndex, lastElIndex){
let array = arr;
let currentIndex = 0;
function partition(firstElIndex, lastElIndex) {
let i = firstElIndex;
let j = lastElIndex;
let pivot = array[lastElIndex];
while(i < j){
while(i < lastElIndex && array[i] < pivot){
const iCopy = i;
const lastCopy = lastElIndex;
i++;
const arrCopy = array.slice();
setTimeout(() => {
drawLines(arrCopy, iCopy, -1, lastCopy, -1);
});
}
while(j > firstElIndex && array[j] >= pivot){
const jCopy = j;
const firstCopy = firstElIndex;
j--;
const arrCopy = array.slice();
setTimeout(() => {
drawLines(arrCopy, -1, jCopy,-1, firstCopy);
});
}
if(i < j){
array.swap(i, j);
}
}
if(array[i] > pivot){
array.swap(i, lastElIndex);
}
return i;
}
if(firstElIndex < lastElIndex){
currentIndex = partition(firstElIndex, lastElIndex);
quickSort(array, firstElIndex, currentIndex - 1);
quickSort(array, currentIndex + 1, lastElIndex);
}
setTimeout(() => {drawLines(array, -1, -1);}, 1000);
}
And here is drawLines()
:
function drawLines(arr, x, y, rightPivot, leftPivot){
let array = arr.slice();
let container = document.getElementById("centerContent");
let line = undefined;
container.innerHTML = '';
for(let i = 0; i < array.length; i++){
let my_length = (array[i]/6.7).toString() + "vw";line = document.createElement("div");
line.className = "line";
if(i === x || i === y){
line.style.borderLeft = (1/7).toString() + "vw solid red";
}
else if(i === rightPivot){
line.style.borderLeft = (1/7).toString() + "vw solid aqua";
}
else if(i === leftPivot){
line.style.borderLeft = (1/7).toString() + "vw solid orange";
}
else{
line.style.borderLeft = (1/7).toString() + "vw solid black";
}
line.style.height = my_length;
container.appendChild(line);
}
}
I apoligize if the question is poorly structured. It's the my first one. Many thanks in advance.
It sounds like you just want a delay to happen before the line is drawn and also before the loop continues. Using async/await
can do that for you fairly easily. This is a structure you can use:
// to use await you must define the function to be async
async function partition(firstElIndex, lastElIndex) {
let i = firstElIndex;
let j = lastElIndex;
let pivot = array[lastElIndex];
while(i < j){
while(i < lastElIndex && array[i] < pivot){
const iCopy = i;
const lastCopy = lastElIndex;
i++;
const arrCopy = array.slice();
// this line pauses execution for 1 second
await new Promise(resolve => setTimeout(resolve, 1000);
drawLines(arrCopy, iCopy, -1, lastCopy, -1);
}
while(j > firstElIndex && array[j] >= pivot){
const jCopy = j;
const firstCopy = firstElIndex;
j--;
const arrCopy = array.slice();
// this line pauses execution for 1 second
await new Promise(resolve => setTimeout(resolve, 1000);
drawLines(arrCopy, -1, jCopy,-1, firstCopy);
}
if(i < j){
array.swap(i, j);
}
return i;
}
}
and since partition
is now an async function you need to do this when calling it:
if(firstElIndex < lastElIndex){
currentIndex = await partition(firstElIndex, lastElIndex);
quickSort(array, firstElIndex, currentIndex - 1);
quickSort(array, currentIndex + 1, lastElIndex);
}
That requires that quickSort
is also and async
function which means it returns a Promise object that can be either waited for too, or use .then
to know when it's complete.
The first thing is that the setTimeout needs a 2nd parameter with the amount of time to wait, so written like this:
setTimeout(() => {
drawLines(arrCopy, iCopy, -1, lastCopy, -1);
});
will not wait for any amount of time, unless you pass it a 2nd argument like:
setTimeout(() => {
drawLines(arrCopy, iCopy, -1, lastCopy, -1);
}, 500);
I think you where on the correct path when creating that sleep function; indeed it wouldn't work when running the timeout inside the loop. But there's no need to return a Promise. Just try:
function sleep(callback, ...callbackParameters) {
setTimeout(() => callback(...callbackParameters), 500) // remember your timer
}
And then pass whatever function you want to run after the timeout to your sleep function like: sleep(drawLines, arrCopy, iCopy, -1, lastCopy, -1)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.