Как установить таймаут между каждой итерацией в Javascript? - PullRequest
1 голос
/ 21 апреля 2020

Я пытаюсь установить время ожидания (время ожидания) между каждым вызовом drawLines() внутри setTimeout() через некоторое время -l oop.

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);
                });
            }

Я уже пытался установить ожидание время, подобное этому

setTimeout(() => {drawLines(arrCopy, iCopy, -1, lastCopy, -1);}, 1000);

... но тайм-аут происходит до повторного вызова drawLines() без ожидания между вызовами.

Я также пытался

setTimeout(async() => {
           drawLines(arrCopy, iCopy, -1, lastCopy, -1);
           await sleep(1000);
});

. ..с

function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

... но ничего не произошло

Вот вся функция:

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);
}

А вот 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);
    }
}

Прошу прощения, если вопрос плохо структурирован. Это мой первый. Большое спасибо заранее.

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Во-первых, для setTimeout необходим второй параметр с количеством времени ожидания, поэтому запись записана так:

setTimeout(() => {
  drawLines(arrCopy, iCopy, -1, lastCopy, -1);
});

не будет ждать какое-то время, если вы не передадите ему 2-й аргумент вроде:

setTimeout(() => {
  drawLines(arrCopy, iCopy, -1, lastCopy, -1);
}, 500);

Я думаю, что вы находитесь на правильном пути при создании этой функции сна; на самом деле это не сработает при запуске тайм-аута внутри l oop. Но нет необходимости возвращать обещание. Просто попробуйте:

function sleep(callback, ...callbackParameters) {
  setTimeout(() => callback(...callbackParameters), 500)  // remember your timer
}

и затем передайте любую функцию, которую вы хотите запустить после тайм-аута, функции сна, например: sleep(drawLines, arrCopy, iCopy, -1, lastCopy, -1)

0 голосов
/ 21 апреля 2020

Звучит так, будто вы просто хотите, чтобы задержка произошла до того, как линия проведена, а также до того, как l oop продолжится. Использование async/await может сделать это для вас довольно легко. Это структура, которую вы можете использовать:

// 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;
  }
}

и, поскольку partition теперь является асинхронной c функцией, вам необходимо сделать это при вызове:

if(firstElIndex < lastElIndex){
  currentIndex = await partition(firstElIndex, lastElIndex);
  quickSort(array, firstElIndex, currentIndex - 1);
  quickSort(array, currentIndex + 1, lastElIndex);
}

Это требует что quickSort также является функцией async, что означает, что он возвращает объект Promise, который можно либо ожидать, либо использовать .then, чтобы узнать, когда он завершится.

...