递归异步/等待崩溃React App

时间:2018-05-26 08:16:35

标签: javascript reactjs recursion async-await mergesort

我正在尝试创建一个React App,它使用各种参数对各种排序算法进行建模。我试图在算法的每一步创建一个可变延迟,以便让它以人类可理解的速度发生。我写了这个睡眠功能来做到这一点:

sleep = (ms = this.state.delay) => {
    return new Promise(resolve => setTimeout(resolve, ms));
}

然后根据需要创建async排序函数await this.sleep()。它适用于冒泡排序,选择排序和插入排序,但当我尝试合并排序时应用程序崩溃。我认为这是由于递归,但我很难过。

async mergeSort(arr) {
    if(arr.length < 2) {
        return arr;
    }
    const m = Math.floor(arr.length / 2);
    let left = arr.slice(0, m);
    let right = arr.slice(m);

    await this.sleep();

    return this.merge(this.mergeSort(left), this.mergeSort(right));


}

async merge(left, right) {
    let result = [];

    while(left.length && right.length) {
        if(left[0].props.number <= right[0].props.number) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
        await this.sleep();
    }

    while(left.length) {
        result.push(left.shift());
        await this.sleep();
    }

    while(right.length) {
        result.push(right.shift());
        await this.sleep();
    }

    return result;
}

这是我得到的错误:

Objects are not valid as a React child (found: [object Promise]). 
If you meant to render a collection of children, use an array instead.

但是我没有将Promises指定为要渲染的元素,所以我不确定是什么问题。

编辑:这是渲染方法:

render() {
    let {sorted, hatArray, sortingMethod, startTime, endTime, numberOfHats, sorting} = this.state;
    return (
        <div>
            <SortMenu 
                onOptionSelect={this.onOptionSelect} 
                onSortBtn={this.onSortBtn} 
                onHatInputChange={this.onHatInputChange}
                updateHatArray={this.updateHatArray}
                setDelay={this.setDelay}
                sorting={sorting}
            />
            <Modal 
                open={sorted} 
                onClose={this.onCloseModal} 
                classNames={{
                    modal: 'custom-modal',
                    closeIcon: 'modal-close-button'
                }}
                center 
            >
                <h1>Sorting Complete!</h1>
                <p>{`${sortingMethod} sorted ${numberOfHats} hats in ${(endTime - startTime) / 1000} seconds.`}</p>
            </Modal>
            <div id="hat-box">
                {hatArray}
            </div>
        </div>
    );
}

1 个答案:

答案 0 :(得分:0)

解决了!感谢user3210641和Lyosha Korogada的输入。

我更改了合并排序,因此它没有返回值,而是更改了另一个数组。然后我在我去的时候将状态设置为该数组。

如果将sleep函数放入merge()函数内部,它会混淆排序顺序,但我能够将它放在mergeSort()函数中,并且可变秒数来实现相同的目标结果

async mergeSort(l, r) {
    if(l < r) {
        console.log(l);
        const m = Math.floor((l + r) / 2);
        this.mergeSort(l, m);
        this.mergeSort(m + 1, r);
        await this.sleep((r - l) * this.state.delay);
        this.merge(l, m, r);    
    }
}

merge(l, m, r) {
    let left = this.globalHatArray.slice(l, m + 1);
    let right = this.globalHatArray.slice(m + 1, r + 1);
    let ptr = l;
    while(left.length && right.length) {
        if(left[0].props.number <= right[0].props.number) {
            this.globalHatArray[ptr] = left.shift();
        } else {
            this.globalHatArray[ptr] = right.shift();
        }
        ptr++;
    }

    while(left.length) {
        this.globalHatArray[ptr] = left.shift();
        ptr++;
    }

    while(right.length) {
        this.globalHatArray[ptr] = right.shift();
        ptr++;
    }
    this.setState({hatArray: this.globalHatArray});
}