Прекратить выполнение других функций после использования await? - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть некоторые проблемы с использованием рекурсии с "async" и "await". В приведенном ниже коде я создал функцию «wait», возвращающую обещание, которое я вызываю в другой функции «Partition» для добавления некоторой задержки в цикл. После этого я вызываю эту функцию внутри «QuickSort» для реализации некоторой рекурсии. Первый вызов функции "разбиения" внутри выполнен как ожидалось. После этого значение передается внутри обратного вызова «then», чтобы начать выполнение функции «быстрой сортировки», но после выполнения первого «await» внутри этой рекурсии код переходит ко второй рекурсии второй функции «quickSort» внутри обратного вызова. «затем», не заканчивая первую предыдущую рекурсию.

Я предполагаю, что такое поведение ожидается, потому что я использую «асинхронный» «асинхронный» в функции секционирования, так что это позволяет выполнять другой код.

 * delay in some functions. This works wll
 * in loops with the use of 'async' and 'await'
 * @param {int} ms - The time to delay;
 */
function wait(ms) {
  return new Promise(r => setTimeout(r, ms));
}
/**
 * This function perform the partition in an
 * array to perform the Quick Sort
 * @param {int} array - The numbers to be sorted
 * @param {int} low - The low index of the array
 * @param {int} high - The high index of the array
 */
async function partition(array, low, high) {
  /* This pivot is place at the rigth position */
  var pivot = array[high];
  var index = low - 1;
  /* Get all the columns child nodes */
  var columnNodes = document.getElementById("flex-box").childNodes;
  var parentElement = document.getElementById("flex-box");
  /* Change the color of the Pivot */
  var pivotColumnNode = columnNodes[high];
  pivotColumnNode.style.backgroundColor = "pink";

  for (let i = low; i < high; i++) {

    // /* Reset the color of the previous Index nodes */
    // if (columnNodes[i - 1] !== undefined) {
    //   columnNodes[i - 1].style.backgroundColor = "blueviolet";
    // }
    /* Change color of value being compare to Pivot node */
    var iNode = columnNodes[i];
    // iNode.style.backgroundColor = "red";
    if (array[i] < pivot) {
      index += 1;
      //Replace the values
      var valueofIndexElement = array[index];
      array[index] = array[i];
      array[i] = valueofIndexElement;

      /* Chnage the color of the node index to be chnanged */
      var nodeIndexElement = columnNodes[index];
      iNode.style.backgroundColor = "yellow";
      nodeIndexElement.style.backgroundColor = "brown";

      var nodeIndexElementClone = nodeIndexElement.cloneNode(true);
      var nodeIElementClone = iNode.cloneNode(true);

      parentElement.replaceChild(nodeIElementClone, columnNodes[index]);
      parentElement.replaceChild(nodeIndexElementClone, columnNodes[i]);
      //await wait(1000);
      nodeIElementClone.style.backgroundColor = "blueviolet";
      nodeIndexElementClone.style.backgroundColor = "blueviolet";
    }
    console.log("New Array: ", array);
    console.log("*********************************");
  }
  var valueOfLastGreaterElement = array[index + 1];
  array[index + 1] = pivot;
  array[high] = valueOfLastGreaterElement;

  /* Chnage the last node elements */
  var pivotColumnNodeClone = pivotColumnNode.cloneNode(true);
  var greaterColumnNodeClone = columnNodes[index + 1].cloneNode(true);

  parentElement.replaceChild(pivotColumnNodeClone, columnNodes[index + 1]);
  parentElement.replaceChild(greaterColumnNodeClone, columnNodes[high]);
  /* Reset the color of the Pivot node */
  pivotColumnNodeClone.style.backgroundColor = "blueviolet";
  greaterColumnNodeClone.style.backgroundColor = "blueviolet";

  console.log("Last: ", array);
  return index + 1;
}
/**
 * This sorts the array with the help of the partition
 * function. This uses recursion to divide an conquer the
 * array.
 * @param {int} array - The numbers to be sorted.
 * @param {*} low - The first index of the array '0'
 * @param {*} high - The length of the array.
 */
function quickSort(array, low, high) {
  debugger;
  if (low < high) {
    debugger;
    partition(array, low, high).then(value => {
      debugger;
      alert(value);
      quickSort(array, low, value - 1); // Before the partition index
      quickSort(array, value + 1, high); // After the partition index
    });
    debugger;
    // partition(array, low, high).then(value => {
    //   debugger;
    //   alert(value);
    //   quickSort(array, value + 1, high); // After the partition index
    // });
  }
}

То, чего я хочу достичь, это как использовать await в функции разделения и рекурсивно использовать эту функцию в функции «QuickSort».

1 Ответ

0 голосов
/ 07 ноября 2019

Да, ваша функция quicksort также выполняет некоторые асинхронные действия, когда она вызывает функцию async partition. Но в коде

quickSort(array, low, value - 1); // Before the partition index
quickSort(array, value + 1, high); // After the partition index

вторые вызовы не ожидают завершения первого, поэтому они будут одновременно выполнять два разбиения. Вам нужно объединить их в цепочку - используя явное объединение обещаний

function quickSort(array, low, high) {
  if (low < high) {
    return partition(array, low, high).then(value => {
      alert(value);
      return quickSort(array, low, value - 1).then(() => { // Before the partition index
        return quickSort(array, value + 1, high); // After the partition index
      });
    });
  } else {
    return Promise.resolve();
  }
}

или используя синтаксис async / await:

async function quickSort(array, low, high) {
  if (low < high) {
    const value = await partition(array, low, high)
    alert(value);
    await quickSort(array, low, value - 1); // Before the partition index
    await quickSort(array, value + 1, high); // After the partition index
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...