【问题标题】:Stop executing other functions after using await?使用 await 后停止执行其他功能?
【发布时间】:2019-11-07 08:24:41
【问题描述】:

我在使用带有“async”和“await”的递归时遇到了一些问题。在下面的代码中,我创建了一个函数“wait”,它返回一个 Promise,我在另一个函数“Partition”中调用它以在循环中添加一些延迟。之后,我在“QuickSort”中调用这个函数来实现一些递归。内部“分区”函数的第一次调用按预期执行。在此之后,值在回调“then”中传递以开始执行函数“quicksort”,但在执行此递归中的第一个“await”之后,代码将传递给回调中第二个“quickSort”函数的第二个递归"then" 没有完成前一个递归。

我猜这种行为是意料之中的,因为我在分区函数中使用了“异步”“异步”,所以这允许执行其他代码。

 * 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”函数上以递归的方式使用该函数。

【问题讨论】:

  • 您不能获取异步值并从 Javascript 中的同步函数中返回它。无法完成。我很难理解为什么你的partition() 函数是async。看起来它应该只是一个普通的同步函数,并且在这段代码中的任何地方都不应该使用 Promise。你为什么还要在这段代码中提出异步操作?而且,您永远无法像在其中设计异步操作那样设计快速排序算法。如果它里面有异步操作,那么它需要一个异步返回值或回调。
  • 很抱歉,这个设计总体上是一团糟。您正在尝试将异步操作(甚至似乎不需要异步)注入到同步代码流中。不能那样做。要么摆脱不必要的异步操作并使一切同步,要么您需要重新考虑如何编写异步代码和与quicksort() 不同的接口。
  • 我不知道这是一个纯技术问题,还是您有真正的问题要解决。如果你有一个真正的问题要解决,那么备份几个步骤,跳过你遇到的实施问题,并描述你在这里试图解决的总体问题是什么。也许,实际的问题是对一些 DOM 元素进行排序?而且,为什么这里完全涉及异步?
  • 如果这是一个纯技术问题,那么您无法使用asyncawait 停止整个Javascript 解释器。 await 将暂停一个函数内部的执行,当它这样做时,它会立即返回一个 Promise,然后在该函数调用继续运行之后的其余代码(大概是为了注册对该 Promise 的兴趣并做其他事情)。所以,你不只是阻止整个解释器等待一个承诺解决。它不是那样工作的。 async 函数仍然是非阻塞的。它只是在遇到函数内的第一个 await 时返回一个 Promise。
  • 感谢 @jfriend00 的 cmets。我只是在不使用 Promise 的情况下再次编写代码,所以所有方法都是同步的。

标签: javascript asynchronous recursion promise


【解决方案1】:

是的,您的 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
  }
}

【讨论】:

  • 除了在partition() 函数中实际上没有任何异步内容,因此在quicksort() 函数中。在我看来,这看起来像是 async 关键字的误导用户。不幸的是,OP 似乎已经消失了,所以我没有运气让他们参与这个话题。
  • @jfriend00 //await wait(1000);partition 函数中被注释掉了
  • 没有解释那里是什么/为什么。这似乎很可能也是解决一些未描述问题的错误尝试。如果partition() 有真正的异步原因,那么您的答案很好 - 我不清楚这是一个实际的异步问题。另外,如果您在每次调用partition() 时暂停一秒钟,则可能需要很长时间才能对某些内容进行排序,同时屏幕会跳来跳去,直到最终停止。这是一个太多的XY问题。这里没有描述实际要解决的核心问题。
  • @jfriend00 鉴于partition 函数中发生的所有DOM 操作,我突然想到它正在做一些排序算法的动画。确实,如果不是这样,那么这可能是在做其他事情的错误尝试。
  • 谢谢,@Bergi。事实上,在递归函数中使用 await 是可行的。我将此作为我当前的解决方案实施。但是,我正在考虑使所有方法同步,这样代码会更准确。谢谢,
猜你喜欢
  • 1970-01-01
  • 2019-10-22
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多