确定性API调用指的是在相同输入条件下总是产生相同输出的API请求。这类调用通常不依赖外部状态或时间因素,结果可预测且可重复。
Redux是一个用于JavaScript应用的状态管理库,它使用单一的不可变状态树来存储整个应用的状态,并通过纯函数(reducers)来修改状态。
当确定性API调用与Redux存储结合使用时,可能会遇到以下问题:
// 使用redux-thunk中间件实现请求去重
const fetchSomeData = (params) => {
return async (dispatch, getState) => {
const { data } = getState();
const cacheKey = JSON.stringify(params);
// 检查是否已有相同请求在进行中
if (data.pendingRequests.includes(cacheKey)) {
return;
}
// 标记请求为进行中
dispatch({ type: 'REQUEST_STARTED', payload: cacheKey });
try {
const response = await api.fetchData(params);
dispatch({ type: 'REQUEST_SUCCESS', payload: { cacheKey, data: response } });
} catch (error) {
dispatch({ type: 'REQUEST_FAILED', payload: { cacheKey, error } });
}
};
};
// reducer中实现缓存逻辑
const dataReducer = (state = { cache: {}, pendingRequests: [] }, action) => {
switch (action.type) {
case 'REQUEST_STARTED':
return {
...state,
pendingRequests: [...state.pendingRequests, action.payload]
};
case 'REQUEST_SUCCESS':
return {
...state,
cache: {
...state.cache,
[action.payload.cacheKey]: action.payload.data
},
pendingRequests: state.pendingRequests.filter(
key => key !== action.payload.cacheKey
)
};
case 'REQUEST_FAILED':
return {
...state,
pendingRequests: state.pendingRequests.filter(
key => key !== action.payload.cacheKey
)
};
default:
return state;
}
};
// 自定义中间件处理确定性API调用
const deterministicApiMiddleware = store => next => action => {
if (action.type === 'API_CALL' && action.meta?.deterministic) {
const state = store.getState();
const cacheKey = action.meta.cacheKey || JSON.stringify(action.payload);
// 检查缓存
if (state.apiCache[cacheKey]) {
return next({
type: 'API_CACHE_HIT',
payload: state.apiCache[cacheKey],
meta: { cacheKey }
});
}
// 标记为进行中
next({
type: 'API_CALL_STARTED',
meta: { cacheKey }
});
// 实际API调用
return apiCall(action.payload)
.then(response => {
return next({
type: 'API_CALL_SUCCESS',
payload: response,
meta: { cacheKey, deterministic: true }
});
})
.catch(error => {
return next({
type: 'API_CALL_FAILED',
payload: error,
meta: { cacheKey }
});
});
}
return next(action);
};
通过以上方法,可以有效解决确定性API调用与Redux存储结合时产生的问题,提高应用性能和用户体验。