如何在 Javascript 中继续之前等待整个递归完成?
How to wait for the whole recursion to finish before moving on in Javascript?
我是 reactJS 的新手,正在尝试构建一个排序可视化工具。我面临的问题是在实施 quickSort() 例程时。
我的 quickSort() 例程如下:
async quickSort(array, p, r) {
if(p<r){
this.Partition(array,p,r).then((q)=>{
console.log(p, ' ', r)
this.quickSort(array, p, q-1)
this.quickSort(array,q+1,r)
})
}
}
我有 .then 和 Partition 函数的原因是因为我在动画的 Partition 例程中使用 async/await。然后 Partition 例程 returns 分区的值 'q' 然后可以发生递归。分区函数 return 是一个承诺,其值为分区值 'q',没有它递归将无法继续,因此“.then”部分。
现在,代码 运行 正确,但我想添加更多功能。我从 quickSortHelper() 例程内部调用此 quickSort() 例程。在 quickSortHelper() 中,我首先禁用一个按钮,然后调用 quickSort() 并在 quickSort() 完成后我想再次启用该按钮。
但问题是 quickSort(array, 0 , n-1) returns 仅在第一次调用它之后立即被禁用和启用,而无需等待整个递归展开。
我尝试从 quickSort() 中 returning 一个 promise,以确保只有当 promise 被解决时,我们才会继续启用按钮。但是 promise 在 1-2 次迭代后解决(这是有道理的,因为 p>r 我认为函数会 return 的那一刻)因此按钮被启用而无需等待整个递归完成。
对于如何解决这个问题,有任何的建议吗?有没有办法暂停执行直到 quickSort() 完成,然后继续启用按钮的工作?
async quickSortHelper(){
this.setState({generateButton: true})
console.log(this.state.generateButton)
var array = this.state.array
this.quickSort(array, 0, array.length-1 ).then(()=>{
this.setState({array})
this.setState({generateButton: false})
})
}
还有一件事,console.log(this.state.generateButton) 输出 false。所以它永远不会将状态设置为真?我不明白为什么会这样?
您的 quickSort
函数目前 return 是一个立即解决且未定义值的承诺。您需要 return 一个承诺,await
它的解决方案。所以要么继续 then
链(然后你真的不需要 async
),要么使用 async
/await
(cf. further down):
function quickSort(array, p, r) {
if (p < r) {
return this.Partition(array,p,r).then((q) => {
// ^^^^^^
console.log(p, ' ', r);
return this.quickSort(array, p, q-1);
// ^^^^^^
}).then(() => {
return this.quickSort(array,q+1,r);
// ^^^^^^
});
}
}
当然,混合使用 async
和 then
有点奇怪,因此您也应该将 then
替换为 await
语法:
async quickSort(array, p, r) {
if (p < r) {
let q = await this.Partition(array,p,r);
console.log(p, ' ', r);
await this.quickSort(array, p, q-1);
await this.quickSort(array,q+1,r);
}
}
注意:使用 semi-colons。当您可以自己控制时,依靠自动分号插入是在放弃控制权。
这应该可以完成工作:
async quickSort(array, p, r) {
if(p<r){
const q = await this.Partition(array,p,r);
console.log(p, ' ', r);
await this.quickSort(array, p, q-1);
await this.quickSort(array,q+1,r);
}
}
我是 reactJS 的新手,正在尝试构建一个排序可视化工具。我面临的问题是在实施 quickSort() 例程时。
我的 quickSort() 例程如下:
async quickSort(array, p, r) {
if(p<r){
this.Partition(array,p,r).then((q)=>{
console.log(p, ' ', r)
this.quickSort(array, p, q-1)
this.quickSort(array,q+1,r)
})
}
}
我有 .then 和 Partition 函数的原因是因为我在动画的 Partition 例程中使用 async/await。然后 Partition 例程 returns 分区的值 'q' 然后可以发生递归。分区函数 return 是一个承诺,其值为分区值 'q',没有它递归将无法继续,因此“.then”部分。
现在,代码 运行 正确,但我想添加更多功能。我从 quickSortHelper() 例程内部调用此 quickSort() 例程。在 quickSortHelper() 中,我首先禁用一个按钮,然后调用 quickSort() 并在 quickSort() 完成后我想再次启用该按钮。
但问题是 quickSort(array, 0 , n-1) returns 仅在第一次调用它之后立即被禁用和启用,而无需等待整个递归展开。
我尝试从 quickSort() 中 returning 一个 promise,以确保只有当 promise 被解决时,我们才会继续启用按钮。但是 promise 在 1-2 次迭代后解决(这是有道理的,因为 p>r 我认为函数会 return 的那一刻)因此按钮被启用而无需等待整个递归完成。
对于如何解决这个问题,有任何的建议吗?有没有办法暂停执行直到 quickSort() 完成,然后继续启用按钮的工作?
async quickSortHelper(){
this.setState({generateButton: true})
console.log(this.state.generateButton)
var array = this.state.array
this.quickSort(array, 0, array.length-1 ).then(()=>{
this.setState({array})
this.setState({generateButton: false})
})
}
还有一件事,console.log(this.state.generateButton) 输出 false。所以它永远不会将状态设置为真?我不明白为什么会这样?
您的 quickSort
函数目前 return 是一个立即解决且未定义值的承诺。您需要 return 一个承诺,await
它的解决方案。所以要么继续 then
链(然后你真的不需要 async
),要么使用 async
/await
(cf. further down):
function quickSort(array, p, r) {
if (p < r) {
return this.Partition(array,p,r).then((q) => {
// ^^^^^^
console.log(p, ' ', r);
return this.quickSort(array, p, q-1);
// ^^^^^^
}).then(() => {
return this.quickSort(array,q+1,r);
// ^^^^^^
});
}
}
当然,混合使用 async
和 then
有点奇怪,因此您也应该将 then
替换为 await
语法:
async quickSort(array, p, r) {
if (p < r) {
let q = await this.Partition(array,p,r);
console.log(p, ' ', r);
await this.quickSort(array, p, q-1);
await this.quickSort(array,q+1,r);
}
}
注意:使用 semi-colons。当您可以自己控制时,依靠自动分号插入是在放弃控制权。
这应该可以完成工作:
async quickSort(array, p, r) {
if(p<r){
const q = await this.Partition(array,p,r);
console.log(p, ' ', r);
await this.quickSort(array, p, q-1);
await this.quickSort(array,q+1,r);
}
}