【问题标题】:Stop function while running in React在 React 中运行时停止功能
【发布时间】:2020-05-05 11:28:59
【问题描述】:

简介

我正在构建一个用于研究目的的排序算法可视化工具,并且我有一个 sortArray() 函数来处理正在排序的数组的动画。正如您在代码中看到的那样。

它工作得很好,但问题是我想让数组需要一些时间来排序,我想要一种在运行时停止这个函数的方法。

到目前为止我已经尝试过什么

在我意识到我遇到了这个问题后,我认为“停止”按钮是解决问题的好方法,我添加了一个名为“Abort”的新状态,最初的想法是 sortArray()函数正在运行,该函数将每次检查中止状态是否设置为真,如果是,则该函数将停止。当然,它没有用。

在我之前的尝试失败之后,我从代码中删除了“abort”状态并将其转换为普通变量,认为问题可能与 setState 函数异步有关,但并没有也可以工作。

之后我做了一些研究,但没有发现任何有用的东西。

代码:

resetArray(){
        const arrayToSort = [];
        const prevChanged = [];
        for (let i = 0; i < this.state.numberOfItems; i++) {
            arrayToSort.push(this.RandomIntBetweenRange(5, 1000));
        }
        this.setState({ arrayToSort, prevChanged, abort: false });
    }

generateNewArray(){
    this.setState({abort: true},{
        this.resetArray();
    });
}

async SortArray(algo){
    let sortedArrayAnim = algo(this.state.arrayToSort);
    let arrayToSort = this.state.arrayToSort;
    let prevChanged = this.state.prevChanged;

    for (let index = 0; index < sortedArrayAnim.length; index++) {
        const [i,j] = sortedArrayAnim[index];

        if(this.state.abort){
            console.log(abort);
            return null;
        }
            let temp = arrayToSort[i];
            arrayToSort[i] = arrayToSort[j];
            arrayToSort[j] = temp;

            prevChanged.push(i,j);

            if(index == sortedArrayAnim.length - 1){
                prevChanged.push(arrayToSort.length + 1, arrayToSort.length + 1);
                this.setState({prevChanged});
            }

            this.setState({ arrayToSort,prevChanged });
            await sleep(10);
    }
}

render() {
    const {arrayToSort} = this.state;
    return (
        <div className="main-div">
            {arrayToSort.map((value, idx) => (
                <div className="array-item" key={idx} style={{height: value, width: 800 / this.state.numberOfItems, backgroundColor: this.getColor(idx)}}>

                </div>
            ))}

            <button onClick={() => this.generateNewArray()}>Generate new array</button>
            <button onClick={() => this.SortArray(BubbleSort)}>Bubble Sort</button>
            <button onClick={() => this.SortArray(InsertionSort)}>Insertion Sort</button>
            <button onClick={() => this.SortArray(QuickSort)}>Quick Sort</button>
            <input type="number" min="5" max="1500" onChange={(event) => this.handleOnChange(event)} defaultValue={this.state.numberOfItems}/>
        </ div>
    );
}

【问题讨论】:

    标签: javascript node.js reactjs asynchronous


    【解决方案1】:

    你能做一些涉及网络工作者的事情吗?

    像这样构造类

    class LongOperation extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          running: false,
          results: null,
          worker: null,
        }
      }
    
      startLongOp(){
         const worker = new Worker('yourIsolatedOp.js')
         //...setup
         this.setState({
           running: true,
           worker: worker,
         })
      }
    
      cancel() {
        if(running) { 
          this.state.worker.terminate() 
        }
        this.setState({
          running: false, 
          worker: null,
        })
      }
    
      render() {
       //Do your rendering
       <button onClick={e => this.startLongOp()}>Start</button>
       <button onClick={e => this.cancel()}>Cancel</button>
      }
    }
    
    //while loop:
    while(this.state.running) {
      //do stuff
    }
    

    您也可以使用 while 循环来执行此操作,但它会在 UI 线程上。我没有尝试过,这只是我头顶的草图。现在设计并发排序将成为更大的挑战......如果你可以隔离它,worker 将是最简单的。

    *注意:我没有详细说明如何处理 web-worker 传递数据等。但是你可以很容易地找到它。我认为您没有理由不能从这些消息中更新状态。

    【讨论】:

      猜你喜欢
      • 2013-08-11
      • 1970-01-01
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 2022-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多