当其中一个获取延迟响应时,如何在 Redux 中使用多个获取执行操作?
How to make an action in Redux with multiple fetches when one of them gets response with delay?
我正在考虑如何在 Redux 中实现以下操作:
- 第一次提取获取带有其 id 的搜索数据(api 端点:
/searches/:id
)
- 其响应有
status
,可以等于in_progress
或finished
- 仅当第一个请求的响应等于
finished
时,我才需要 运行 第二次提取
- 第二次提取采用相同的 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
}
})
}
这种方式行不通。我什至不确定我是否正在尝试以正确的方式进行。我需要有关如何实施此类操作的帮助或想法。
@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);
它并不完美,但它给了你一个想法。
我认为你不应该将 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
});
我正在考虑如何在 Redux 中实现以下操作:
- 第一次提取获取带有其 id 的搜索数据(api 端点:
/searches/:id
) - 其响应有
status
,可以等于in_progress
或finished
- 仅当第一个请求的响应等于
finished
时,我才需要 运行 第二次提取
- 第二次提取采用相同的 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
}
})
}
这种方式行不通。我什至不确定我是否正在尝试以正确的方式进行。我需要有关如何实施此类操作的帮助或想法。
@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);
它并不完美,但它给了你一个想法。
我认为你不应该将 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
});