简体   繁体   English

如何在 Javascript 中的每次迭代之间设置超时?

[英]How to set a timeout between each iteration in Javascript?

I am trying to set a timeout(wait time) between each call of drawLines() inside a setTimeout() in a while-loop.我正在尝试在 while 循环中的setTimeout() drawLines() ) 之间设置超时(等待时间)。

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. ...但是超时发生在重复调用drawLines()之前,而无需在调用之间等待。

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:

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() :这是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.使用async/await可以很容易地为您做到这一点。 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:并且由于partition现在是异步 function 您需要在调用它时执行此操作:

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.这要求quickSort也是async function 这意味着它返回一个 Promise object 也可以等待,或者使用.then来知道它什么时候完成。

The first thing is that the setTimeout needs a 2nd parameter with the amount of time to wait, so written like this:第一件事是 setTimeout 需要一个带有等待时间的第二个参数,所以写成这样:

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;我认为你在创建睡眠 function 时在正确的路径上; indeed it wouldn't work when running the timeout inside the loop.确实在循环内运行超时时它不起作用。 But there's no need to return a Promise.但是没有必要返回 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)然后将你想在超时后运行的任何 function 传递给你的睡眠 function 像: sleep(drawLines, arrCopy, iCopy, -1, lastCopy, -1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM