这里只放了核心代码,具体完整的代码可以去仓库里看看github地址 这里本地存储数据用到的库官方文档地址AsyncStorage
代码语言:javascript复制import AsyncStorage from '@react-native-async-storage/async-storage';
export const FLAG_STORAGE = {
flag_popular: 'popular',
flag_trending: 'trending',
};
export default class DataStore {
/**
* 获取数据,优先获取本地数据,如果无本地数据或本地数据过期则获取网络数据
* @param url
* @param flag
* @returns {Promise}
*/
fetchData(url, flag) {
return new Promise((resolve, reject) => {
this.fetchLocalData(url)
.then(wrapData => {
if (wrapData && DataStore.checkTimestampValid(wrapData.timestamp)) {
resolve(wrapData);
} else {
this.fetchNetData(url, flag)
.then(data => {
resolve(this._wrapData(data));
})
.catch(error => {
reject(error);
});
}
})
.catch(error => {
this.fetchNetData(url, flag)
.then(data => {
resolve(this._wrapData(data));
})
.catch(error => {
reject(error);
});
});
});
}
/**
* 保存数据
* @param url
* @param data
* @param callback
*/
saveData(url, data, callback) {
if (!data || !url) return;
AsyncStorage.setItem(url, JSON.stringify(this._wrapData(data)), callback);
}
/**
* 获取本地数据
* @param url
* @returns {Promise}
*/
fetchLocalData(url) {
return new Promise((resolve, reject) => {
AsyncStorage.getItem(url, (error, result) => {
if (!error) {
try {
resolve(JSON.parse(result));
} catch (e) {
reject(e);
console.error(e);
}
} else {
reject(error);
console.error(error);
}
});
});
}
/**
* 获取网络数据
* @param url
* @param flag
* @returns {Promise}
*/
fetchNetData(url, flag) {
return new Promise((resolve, reject) => {
// if (flag !== FLAG_STORAGE.flag_trending) {
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
})
.then(responseData => {
this.saveData(url, responseData);
resolve(responseData);
})
.catch(error => {
reject(error);
});
// }
// else {
// new Trending()
// .fetchTrending(url)
// .then(items => {
// if (!items) {
// throw new Error('responseData is null');
// }
// this.saveData(url, items);
// resolve(items);
// })
// .catch(error => {
// reject(error);
// });
// }
});
}
_wrapData(data) {
return {data: data, timestamp: new Date().getTime()};
}
/**
* 检查timestamp是否在有效期内
* @param timestamp 项目更新时间
* @return {boolean} true 不需要更新,false需要更新
*/
static checkTimestampValid(timestamp) {
const currentDate = new Date();
const targetDate = new Date();
targetDate.setTime(timestamp);
if (currentDate.getMonth() !== targetDate.getMonth()) return false;
if (currentDate.getDate() !== targetDate.getDate()) return false;
if (currentDate.getHours() - targetDate.getHours() > 4) return false; //有效期4个小时
// if (currentDate.getMinutes() - targetDate.getMinutes() > 1)return false;
return true;
}
}
代码语言:javascript复制import Types from '../types';
import DataStore, {FLAG_STORAGE} from '../../expand/dao/DataStore';
import {_projectModels, handleData} from '../ActionUtil';
/**
* 获取最热数据的异步action
* @param storeName
* @param url
* @param pageSize
* @param favoriteDao
* @returns {function(*=)}
*/
export function onRefreshPopular(storeName, url, pageSize, favoriteDao) {
return dispatch => {
dispatch({type: Types.POPULAR_REFRESH, storeName: storeName});
let dataStore = new DataStore();
dataStore
.fetchData(url, FLAG_STORAGE.flag_popular) //异步action与数据流
.then(data => {
handleData(
Types.POPULAR_REFRESH_SUCCESS,
dispatch,
storeName,
data,
pageSize,
favoriteDao,
);
})
.catch(error => {
console.log(error);
dispatch({
type: Types.POPULAR_REFRESH_FAIL,
storeName,
error,
});
});
};
}
/**
* 加载更多
* @param storeName
* @param pageIndex 第几页
* @param pageSize 每页展示条数
* @param dataArray 原始数据
* @param callBack 回调函数,可以通过回调函数来向调用页面通信:比如异常信息的展示,没有更多等待
* @param favoriteDao
* @returns {function(*)}
*/
export function onLoadMorePopular(
storeName,
pageIndex,
pageSize,
dataArray = [],
favoriteDao,
callBack,
) {
return dispatch => {
setTimeout(() => {
//模拟网络请求
if ((pageIndex - 1) * pageSize >= dataArray.length) {
//已加载完全部数据
if (typeof callBack === 'function') {
callBack('no more');
}
dispatch({
type: Types.POPULAR_LOAD_MORE_FAIL,
error: 'no more',
storeName: storeName,
pageIndex: --pageIndex,
});
} else {
//本次和载入的最大数量
let max =
pageSize * pageIndex > dataArray.length
? dataArray.length
: pageSize * pageIndex;
_projectModels(dataArray.slice(0, max), favoriteDao, data => {
dispatch({
type: Types.POPULAR_LOAD_MORE_SUCCESS,
storeName,
pageIndex,
projectModels: data,
});
});
}
}, 500);
};
}
/**
* 刷新收藏状态
* @param storeName
* @param pageIndex 第几页
* @param pageSize 每页展示条数
* @param dataArray 原始数据
* @param favoriteDao
* @returns {function(*)}
*/
export function onFlushPopularFavorite(
storeName,
pageIndex,
pageSize,
dataArray = [],
favoriteDao,
) {
return dispatch => {
//本次和载入的最大数量
let max =
pageSize * pageIndex > dataArray.length
? dataArray.length
: pageSize * pageIndex;
_projectModels(dataArray.slice(0, max), favoriteDao, data => {
dispatch({
type: Types.FLUSH_POPULAR_FAVORITE,
storeName,
pageIndex,
projectModels: data,
});
});
};
}