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