React JS-为每个表行调用相同的API端点,直到响应包含某些条件

时间:2019-12-09 22:50:42

标签: reactjs api asynchronous

我有一个应用程序,它需要为表的每一行调用相同的端点,但需要使用不同的参数。

到目前为止,我的应用程序如下所示:

Table Data

这将执行以下操作:

单击“生成旅程”按钮时,它将把一堆数据发布到服务器并获得如下响应:

{
  "id": 1,
  "customerId": "db7dab81-0b33-41d3-a4a9-861a45c282b5",
  "serviceId": "ac1f0b6f-593e-4377-9697-d8dbe06c6309",
  "numberOfJourneys": 3,
  "generationStatus": "QUEUED",
}

注意QUEUED状态。后端将生成旅程,完成后,状态将更改为COMPLETED

创建旅程后,我们可以通过单击“仿真”按钮进行仿真,然后依次将一些数据发布到另一个API并模拟旅程。

现在我的问题是这个

实现此功能的最佳方法是什么?因为我将不得不针对每个表行反复调用端点以检查状态是否为COMPLETED才能模拟旅程。

到目前为止,我目前还没有解决方案,但正在按照以下思路进行思考:

getJourneyEmulations() {
    let promise;
    promise = journeyCreationStatus();

    if (!promise) {
        return;
    }

    this.setState({
        isLoading: true
    });

    promise.then(response => {
        const generationStatus = this.state.generationStatus;
        this.setState({
            generationStatus: generationStatus,
            isLoading: false
        })
    }).catch(error => {
        this.setState({
            isLoading: false
        });
        console.log(error);
    })
}

然后使用componentDidMount中的计时器来调用它,如:

 componentDidMount() {
    this.getRouteGenerations();
    this.timer = setInterval(()=> this.getJourneyEmulations(), 10000)
}

但是,我认为这不会奏效,因为我需要为每个表行调用它。

如果需要更多解释,请发表评论,我会尽力解释。

谢谢

1 个答案:

答案 0 :(得分:0)

因此,存在多种类型的问题,例如长时间轮询或websocket,但我将假定您无权访问服务器,因此唯一的选择是反复调用服务器。

此外,我想您会在开始时发送一个POST,然后端点(或其他端点)会通过GET通知您generationStatus是否已完成的天气信息。

多次获取直到成功的代码如下:

const url = 'your/api/url/';
const INTERVAL_MS = 5000;

function delay() {
  return new Promise(resolve => setInterval(resolve, INTERVAL_MS))
}

function isCompleted(data) {
  return data.generationStatus === 'COMPLETED'
}

function postJourney(data) {
  return fetch(
    url,
    {
      method:'POST',
      body:JSON.stringify(data)
    })
    .then(response => response.json())
}

function checkStatusUntilCompleted() {
  return fetch(url)
    .then(response => response.json())
    .then(json => {
    if (!isCompleted(json)) {
      // we retry after some delay if it was not completed
      return delay().then(checkStatusUntilCompleted)
    }
    else {
      return Promise.resolve(json)
    }
  })
}

function postJourneyAndCheckUntilCompleted(rowData) {
  postJourney(rowData)
    .then(json => {
    if (!isCompleted(json)) {
      return delay().then(checkStatusUntilCompleted)
    }
    else {
      return Promise.resolve(json)
    }
  })
  .then((data) => {
    // do stuff, it is completed now
  })
}

此外,您可能要处理HTTP错误,CSRF令牌和/或使用自定义提取包装器。

然后,您将通过以下方式从render函数调用postJourney:

rowDatas.map((rowData) => (
   <TableRow key={rowData.key}>
      <Cell>{rowData.customerId}</Cell>
      /* ... */
     <Cell><Button onClick={() => postJourneyAndCheckUntilCompleted(rowData)}>Generate Journey</Button></Cell>
   </TableRow>
)

欢呼