React-Native|AsyncStorage缓存网络数据

第一次请求网络数据时,把数据保存在本地并记录当前时间,下次请求时,如果有本地数据就先显示本地数据,并且判断如果保存该数据的时间与当前时间超过或等于一分钟,再去请求网络更新数据,并保存在本地。

在先前的ListView的基础上改了改:

import ListViewItemDemo from './ListViewItemDemo';
import Toast,{DURATION} from 'react-native-easy-toast';
const URL="http://101.201.78.24/api/activity/list";

export default class ListViewDemo extends Component {

    constructor(props){
        super(props);
        this.state={
            count:0,
            result:'',
            refreshing:true,
            dataSource:new ListView.DataSource({
                rowHasChanged:(r1,r2)=>r1!=r2,
            }),
            isFirstIn:true,
            dataArray:[],
            coffee:'',
        };
    }

    //请求网络数据
    getNetData(url){
        var promise=new Promise((resolve,reject)=>{
            fetch(url).then(response=> response.json()).
            then(result=>{
                this.refs.toast.show("请求网络数据",DURATION.LENGTH_SHORT);
                //在请求网络数据时,把数据保存在本地
                if(!result){
                    reject(new Error('请求网络数据发生错误'));
                    return;
                }
                resolve(result);
                this.saveLocalData(url,result);
            }).
            catch(error=>reject(error));
        });
        return promise;
    }

    //实现缓存功能
    fetchData(url){
        var promise=new Promise((resolve,reject)=>{
            //获取本地数据
            this.getLocalData(url).then(result=>{
                //如果有本地数据,返回给调用者
                if(result){
                    this.refs.toast.show("显示的是本地数据",DURATION.LENGTH_SHORT);
                    resolve(result);
                }else{
                    this.refs.toast.show("第一次请求网络数据",DURATION.LENGTH_SHORT);
                    //没有本地数据,那么去请求网络数据
                    this.getNetData(url).then(result=>{
                        resolve(result)
                    }).catch(error=>{
                        reject(error)
                    })
                }
            })
            //获取本地数据发生异常,则也去请求网络数据
            .catch(error=>{
                this.getNetData(url).then(result=>{
                    resolve(result)
                }).catch(error=>{
                    reject(error)
                })
            })
        });
        return promise;
    }

    //获取本地数据
    getLocalData(url){
        var promise=new Promise((resolve,reject)=>{
            AsyncStorage.getItem(url,(error,result)=>{
                if(error){
                    reject(error);
                }else{
                    //从本地数据库获取的是字符串,转化为构建该字符串的对象
                    try{
                        resolve(JSON.parse(result));
                    }catch (e){
                        reject(e);
                    }
                }
            })
        });
        return promise;
    }

    saveLocalData(url,result){
        if(!url||!result)return;
        let wrapData={
            resultData:result,
            update:new Date().getTime(),
        };
        //保存在本地数据库的是字符串,保存字符串对象会出现错误
        AsyncStorage.setItem(url,JSON.stringify(wrapData),error=>{

        })
    }

    //判断数据
    isUpdate(saveTime){
        let currentDate=new Date();
        let saveDate=new Date()
        saveDate.setTime(saveTime);
        //超过或等于一分钟再去请求网络数据
        if(currentDate.getMinutes()-saveDate.getMinutes()>=1){
            return true;
        }else{
            return false;
        }
    }

    componentDidMount(){
        this.onLoad();
    }

    onRefresh(){
        this.onLoad();
    }

    onLoad(){
        this.setState({
            refreshing:true,
        });
        this.fetchData(URL).then(result=> {
            let realResult=result&&result.resultData?result.resultData:result;
            this.setState({
                dataSource: this.state.dataSource.cloneWithRows(realResult.data.results),
                refreshing:false,
            });
            //如果本地的数据保存的时间和当前时间差值达到一定限度,则需要访问网络
            if(result&&result.update&&this.isUpdate(result.update)){
                return this.getNetData(URL);
            }
        })
            .then(result=>{
                this.setState({
                    dataSource: this.state.dataSource.cloneWithRows(result.data.results),
                    refreshing:false,
                });
            })
            .catch(error=>{
                console.log(error)
            });
    }

    renderRow(item){
        return <ListViewItemDemo item={item}/>
    }

    renderLine(){
        return <View style={styles.line}></View>
    }

    render(){
        return(
            <View style={styles.containers}>
                <ListView
                    dataSource={this.state.dataSource}
                    renderRow={(item)=>this.renderRow(item)}
                    renderSeparator={()=>this.renderLine()}
                    refreshControl={
                        <RefreshControl
                            refreshing={this.state.refreshing}
                            onRefresh={()=>this.onRefresh()}
                        />
                    }
                />
                {/*Toast在根视图的底部去使用,在视图被渲染时,把toast声明*/}
                <Toast
                    ref="toast"/>
            </View>
        )
    }
}

const styles=StyleSheet.create({
    containers: {
        flex:1,
    },
    line:{
        backgroundColor:'red',
        height:0.5,
    }
});

在保存数据的时候,注意把当前的时间也保存下来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值