【发布时间】: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 元素进行排序?而且,为什么这里完全涉及异步?
-
如果这是一个纯技术问题,那么您无法使用
async和await停止整个Javascript 解释器。await将暂停一个函数内部的执行,当它这样做时,它会立即返回一个 Promise,然后在该函数调用继续运行之后的其余代码(大概是为了注册对该 Promise 的兴趣并做其他事情)。所以,你不只是阻止整个解释器等待一个承诺解决。它不是那样工作的。async函数仍然是非阻塞的。它只是在遇到函数内的第一个await时返回一个 Promise。 -
感谢 @jfriend00 的 cmets。我只是在不使用 Promise 的情况下再次编写代码,所以所有方法都是同步的。
标签: javascript asynchronous recursion promise