ReactJS - 如何排队请求(快速按钮点击),并连续处理响应?

ReactJS - How to queue requests (fast button clicks), and handle responses consecutively?

下面的子组件应该显示导航按钮并在按下按钮时呈现适当的结果(第一个、下一个、上一个、最后一个)。不幸的是,由于输入的异步性质(快速按钮按下),我无法捕获所有按钮按下以按顺序处理。我将子组件修改得尽可能简单,但不幸的是它甚至不响应按钮按下,因为我不确定如何处理 属性 的更改,即 this.requests?

我如何根据预期的行为进行这项工作?

子组件

import React from 'react';

export class EditRiskNavigationButtons extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            riskid : props.riskId
        }
        this.requests = []
    }
    queueRequest = (request) => {
        this.requests.push(request);
    }
    handleNextRequest = () => {
        if (this.requests.length) {
            return this.props.getRisk(this.requests.shift());
        }       
    }
    render() {
        return (
            <div>
                <input type="button" value="First" onClick={this.queueRequest.bind(this, 'first')} />
                <input type="button" value="Prev"  onClick={this.queueRequest.bind(this, 'prev')} />
                <input type="button" value="Next"  onClick={this.queueRequest.bind(this, 'next')} />
                <input type="button" value="Last"  onClick={this.queueRequest.bind(this, 'last')} />
            </div>
        );
    }
}

主要成分

import React from 'react';
import { render } from 'react-dom/cjs/react-dom.development';
import { ThemeProvider } from 'styled-jss';
import { formatDateMDY } from '../../common/Functions';
import { EditRiskNavigationButtons } from './EditRiskNavigationButtons';
//import './EditRisk.jss';

class EditRisk extends React.Component {
  constructor(props) {
    super(props)
    this.formatDateMDY = formatDateMDY.bind(this);
    this.getRisk = this.getRisk.bind(this);
    this.state = {
      error: null,
      isLoaded: false,
      risk: [],
      riskid: 0,
      riskAPIUriParams: '',
      message: ''
    };
  }
  getRisk = (gotoRisk = 'first') => {
    this.state.riskAPIUriParams = (this.state.riskid || "") + "/" + gotoRisk
    if (this.state.riskid != 0)
      this.state.riskAPIUriParams = "/" + this.state.riskAPIUriParams;
    return fetch("http://projectaim/api/risks"+this.state.riskAPIUriParams)
    .then(res => res.json())
    .then(
      (result) => {
        this.setState({
          isLoaded: true,
          risk: result.data,
          riskid: result.data.riskid,
          message: result.message
        });
      },
      // Note: it's important to handle errors here
      // instead of a catch() block so that we don't swallow
      // exceptions from actual bugs in components.
      (error) => {
        this.setState({
          isLoaded: true,
          error
        });
      }
    )
  }
  componentDidMount() {
    if (!this.state.isLoaded)
      this.getRisk('first');
  }
  handleSubmit(event){
    
  }
  render() {
    const { error, isLoaded } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
         return (
          <div id="formcontainer">
            <div id="myeditform">   
              <form id="form" name="EditRisk" ng-submit="">
                <div class="layout"></div>
                  <EditRiskNavigationButtons getRisk={this.getRisk} />
                  {JSON.stringify(this.state.risk.riskid)}
              </form>
            </div>
          </div>
        );
    }
  }
}
render(<EditRisk/>, document.getElementById("root"))

不清楚这是否是最终解决方案,但我相信在轮询循环代码中使用 async / await 可以捕获所有请求。任何意见或修改表示赞赏。

import React from 'react';

export class EditRiskNavigationButtons extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            riskid : props.riskId
        }
        this.requests = []
    }
    queueRequest = (request) => {
        this.requests.push(request);
    }
    processNextRequest = async () => {
        var nextRequest;
        if (this.requests.length) {
            nextRequest = this.requests.shift();
        }
        return this.props.getRisk(nextRequest);
    }
    pollForRequests = async () => {
        while (true) {
            await this.processNextRequest();
        }
    }
    componentDidMount() {
       this.pollForRequests();
    }
    render() {
        return (
            <div>
                <input type="button" value="First" onClick={this.queueRequest.bind(this, 'first')} />
                <input type="button" value="Prev"  onClick={this.queueRequest.bind(this, 'prev')} />
                <input type="button" value="Next"  onClick={this.queueRequest.bind(this, 'next')} />
                <input type="button" value="Last"  onClick={this.queueRequest.bind(this, 'last')} />
            </div>
        );
    }
}

我还需要像下面那样将 processNextRequest 修改为 return 等待 this.requests[] 获取至少一个元素的承诺,以防止不必要的循环,除非用户单击一个或多个导航按钮上的次数。

 processNextRequest = async () => {
        var nextRequest;
        if (this.requests.length) {
            nextRequest = this.requests.shift();
            return this.props.getRisk(nextRequest);
        }
        else
        {
            return new Promise((resolve, reject) => {
                setTimeout(() => resolve(this.requests.length));
            });
        }
    }