当其中一个获得延迟响应时,如何在Redux中使用多个提取操作?

时间:2017-10-25 09:51:00

标签: javascript promise redux fetch redux-thunk

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

  1. 第一次获取获取其id(api端点:/searches/:id
  2. 的搜索数据
  3. 其回复有status,可以等于in_progressfinished
  4. 我需要在第一次请求的响应等于finished时才运行第二次获取
  5. 第二次获取使用相同的ID并获取下一个数据(api端点:searches/:id/results
  6. 我对如何进行操作感到困惑,因为我不知道如何重复第一次获取,直到它得到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
        }
      })
    }
    

    它并不是这样的。我甚至不确定我是否正在努力做到这一点。我需要有关如何实施此类行动的帮助或想法。

2 个答案:

答案 0 :(得分: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);

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

答案 1 :(得分:0)

我认为你不应该将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;
    }
  },

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

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 
 });