redux解决异步操作方法
优点: 库小,代码就几行
缺点:代码臃肿,reducer不再是纯粹函数,直接返回对象,违背了当初的设计原则
优点: 将异步与reducer区分开了,更加优雅,适合大量APi请求,而且每个请求之间存在复杂的以来关系
缺点:
1 学习曲线比较陡,理解async await
2 而且库也比较大,即使发布的最小也有25kb,gzip压缩后也有7KB,React压缩后才45kb
解决两次请求,数据延迟,显示不一致的问题
1 当前为北京,点击上海天气,dispatch请求
2 立马点击北京天气,dispatch请求
3 由于网络问题,北京的数据先到,然后更新界面,显示北京的天气
接着上海的数据猜到,此时更新界面为上海的天气
结果: 此时页面选择的是北京的按钮,结果却显示了上海的天气
let nextSeqId = 1
export const fetchWeather = (cityCode) => {
return (dispatch) => {
const apiUrl = `/data/cityinfo/${cityCode}.html`;
const seqId = ++ nextSeqId;
// 数据返回后,判定当前返回数据的请求ID是否是其对应请求的ID
//第一次请求 seqId = 1, nextSeqID = 1
// 第二次请求,seqId = 2, nextSeqID = 2
//如果第二次请求后,结果第二次请求的数据先回来,先更新
// 接着第一次请求数据回来,发现seqId=1,nextSeqID=2,而这不同,就不会再次更新界面
const dispatchIfValid = (action) => {
if (seqId === nextSeqId) {
return dispatch(action);
}
}
dispatchIfValid(fetchWeatherStarted())
fetch(apiUrl).then((response) => {
if (response.status !== 200) {
throw new Error('Fail to get response with status ' + response.status);
}
response.json().then((responseJson) => {
// 数据返回后,取更新界面
dispatchIfValid(fetchWeatherSuccess(responseJson.weatherinfo));
}).catch((error) => {
dispatchIfValid(fetchWeatherFailure(error));
});
}).catch((error) => {
dispatchIfValid(fetchWeatherFailure(error));
})
};
}