当其中一个获取延迟响应时,如何在 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_progress
或finished
只有当第一个请求的响应等于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:当动作完成时组件如何订阅响应?