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

Posted

技术标签:

【中文标题】React JS - 为每个表行调用相同的 API 端点,直到响应包含某些条件【英文标题】:React JS - Call same API endpoint for each table row until response contains certain criteria 【发布时间】:2020-04-03 01:59:53 【问题描述】:

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

到目前为止,我的应用看起来是这样的:

执行以下操作:

当点击 Generate Journey 按钮时,它会向服务器 POST 一堆数据,并得到如下响应:


  "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)

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

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

谢谢

【问题讨论】:

如果您拥有或可以修改服务器,请查看websockets,当QUEUECOMPLETE 时,您可以通知您的客户端 【参考方案1】:

因此,此类问题有多种选择,例如长轮询或 websockets,但我假设您无权访问服务器,因此唯一的选择是重复调用服务器。

另外,我猜你会在开始时发送一个 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 令牌和/或使用自定义提取包装器。

然后您可以通过以下方式从渲染函数调用 postJourney:

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

干杯

【讨论】:

虽然这是很好的轮询代码,但 OP 主要询问如何为 Journey 表中的每一行创建和管理状态更改轮询请求,OP 在问题中演示了处理 ONE 轮询请求的代码已经。 clearInterval 永远不会在 OP 代码中调用,因此它将继续运行。将它用于多行也非常简单,只需使用单击按钮所在行的数据调用 postJourney。 然后调整您的答案以演示管理多行,特别是如果非常直接,OP 直接要求这样做 我无法访问服务器,但我的一位同事可以。实施网络套接字解决方案会更容易吗? 这取决于技术。例如,如果您使用 Django 作为后端,则可能需要更改一些架构(WSGI -> ASGI,可能是一个 Redis 服务器以在多个客户端之间共享事件)。如果您使用的是 Node,则没有那么复杂,但需要一些设置。

以上是关于React JS - 为每个表行调用相同的 API 端点,直到响应包含某些条件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 react.js 动态生成表行

React Hook useEffect :使用 axios 和 async await .api 获取数据,调用连续相同的 api

在 react-redux 应用程序中使用默认错误处理管理 API 调用

React Js API 调用 Jest 测试用例?

React Native - 同步调用restful API

如何根据 React js 中 api 的响应显示成功或错误消息