当其中一个获取延迟响应时,如何在 Redux 中通过多个获取进行操作?

Posted

技术标签:

【中文标题】当其中一个获取延迟响应时,如何在 Redux 中通过多个获取进行操作?【英文标题】:How to make an action in Redux with multiple fetches when one of them gets response with delay? 【发布时间】:2018-04-06 08:32:17 【问题描述】:

我正在考虑如何在 Redux 中实现以下操作:

    第一次 fetch 获取带有 id 的搜索数据(api 端点:/searches/:id) 它的响应有status,它可以等于in_progressfinished 只有当第一个请求的响应等于finished 时,我才需要运行第二个提取 第二次 fetch 采用相同的 id 并获取下一个数据(api 端点:searches/:id/results

我对如何进行操作感到困惑,因为我不知道如何重复第一次获取,直到它得到status: finished 的响应。然后才开始下一次提取以获取结果。

我正在尝试这样做(我正在使用 redux-thunk):

export const fetchResults = (id) => (dispatch) => 
  return fetch(`/searches/$id`, 
    method: 'get',
    headers:  'Content-Type': 'application/json' 
  
  .then(res => res.json())
  .then(data => dispatch(fetchUntilFinished(data.id)))
  .then(res => 
    if (res === true)  // allowed to make next fetch
      fetch(`/searches/$id/results`, 
        method: 'get',
        headers:  'Content-Type': 'application/json' 
      )
      .then(res => res.json())
      .then(results => 
        dispatch(
          type: 'FETCH_RESULTS',
          results: results
        )
      )
    
  )

function fetchUntilFinished(id) 
  fetch(`/searches/$id`, 
    method: 'get',
    headers:  'Content-Type': 'application/json' 
  
  .then(res => res.json())
  .then(data => 
     if (data.status !=== 'finished') 
       fetchUntilFinished(id);
     else 
       return true; // to trigger that next fetch can be done
    
  )

而且这种方式行不通。我什至不确定我是否正在尝试以正确的方式进行操作。我需要有关如何实施此类操作的帮助或想法。

【问题讨论】:

可能有点过分了,但是您是否尝试使用 Promise 包装 fetch 并在获得所需状态时解决该承诺? Fetch 实现了一个类似 Promise 的接口,所以它很适合那里。 @sunpietro 不,真的不知道如何用 Promise 包装它。你能做一个伪代码示例吗? fetchUntilFinished 没有返回任何内容 fetch(/searches/$id, 之前尝试一个return ...在if (data.status !=== 'finished') 块中在fetchUntilFinished(id); 之前尝试另一个 【参考方案1】:

@Dair 你可以试试这样的:

let interval;
const promise = new Promise((resolve, reject) => 
    interval = setInterval(() => 
        fetch('your-url').then((response) => 
            if (response.status === 'finished') 
                clearInterval(interval);
                resolve(response);
            
        )
    , 1000);
);

promise.then(doYourStuffAfterResponse);

它并不完美,但它给了你一个想法。

【讨论】:

即使在状态 === 完成后,此代码仍会继续获取 是的,它会继续抓取。我怎样才能阻止它? 当然会。您必须将间隔存储在变量中,当它达到所需状态时,应使用clearInterval(variableWithIntervalRef) 清除间隔 你能用 clearInterval 编辑你的答案吗? 非常感谢,正在尝试。很快就会有结果!【参考方案2】:

我认为您不应该将 redux 操作与 API 调用混合使用。 他们两个应该是分开的。您可以进行 API 调用。获取数据并在此之后发送操作。这将使您更好地控制数据。 您可能需要对其进行一些格式化,然后才能将其存储在商店中。

我使用 axios 而不是 fetch。但他们都做同样的任务。所以这就是我在这些情况下所做的。 我有一个单独的函数,只调用 api。在一个单独的文件中。为简单起见,我将在一个地方做所有事情。 在此输入代码

function makeRequest(serviceConfig) 

    let serviceObject;
    try 


        serviceObject = 
          url: serviceConfig.baseUrl + serviceConfig.url,
          method: serviceConfig.method,
          params: serviceConfig.params || ,
          data: serviceConfig.data || ,
          headers: serviceConfig.headers || ,
          withCredentials: (serviceConfig.withCredentials === true),
        ;
       
      return axios(serviceObject).then((response) => 
          return  response ;
      , (error) => 
           return error;
      );
     catch (e) 
      throw e;
    
  ,

现在使用所有特定配置调用请求生成函数

requestmaker(
   baseUrlType :'yourdomain.com',
   url:'searches/2',
   method:'GET',
   params:,
   data:,
   headers:
).then((success)=>
     if(success.status==='finished')
     /*call request maker again with new params.*/ 

        requestmaker(
           baseUrlType :'yourdomain.com',
           url:'searches/2/results',
           method:'GET',
           params:,
           data:,
           headers:
       ).then((nextSuccess)=>
         // here nextSuccess will contain the final result set.
          dispatch(
              type: 'FETCH_RESULTS',
               results: nextSuccess
               )
         )
   
 ,(error)=>
 // your error handeler 
 );

【讨论】:

谢谢!稍后将检查您的解决方案。内存泄漏确实是一个大问题。 在 API 方法中使用间隔是不好的,因为它会在您获取数据之前进行服务器调用,因此如果您的网络速度较慢或服务器响应不佳,您可能会结束在多个请求中一个接一个地发送。

以上是关于当其中一个获取延迟响应时,如何在 Redux 中通过多个获取进行操作?的主要内容,如果未能解决你的问题,请参考以下文章

Redux-observable:当动作完成时组件如何订阅响应?

当jackson序列化json对象时如何防止hibernate5延迟获取?

Hibernate延迟加载

Hibernate延迟加载

Hibernate延迟加载

Hhibernate延迟加载