如何在 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);
    //      ^^^^^^
        });
    }   
}

当然,混合使用 asyncthen 有点奇怪,因此您也应该将 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);
    }
}