React Native之基于AsyncStorage的离线缓存框架设计
1.为什么要离线缓存?
宏观上来说:
- 提升用户体验: 我们要为用户提供流畅的APP操作体验,但我们无法保证所有用户的网络流畅度是好的,所以我们需要离线缓存来提升用户体验。
- 节省流量: 节省流量又分为两个层次:
- 节省服务器流量
- 节省用户手机的流量
2.离线缓存的策略

- a. 优先从本地获取数据,如果数据过时或不存在则从服务器获取数据,数据返回后同时将数据同步到本地数据库
- b. 优先从服务器获取数据,数据返回后同时将数据同步到本地数据库,如果网络故障则从本地获取数据
- c. 同时从本地和服务器获取数据,如果本地数据库返回数据则先展示本地数据,等网络数据回来后在展示网络数据同时将数据同步到本地数据库中
3.离线缓存的实现
首先我们需要实现对数的存储
3.1 数据存储
/**
* 保存数据到本地
*
* @param {} url 请求地址
* @param {} data 数据
* @param {} callback 回掉函数
* @returns
* @memberof DataStore
*/
saveData(url, data, callback) {
if (!data || !url) return;
AsyncStorage.setItem(url, JSON.stringify(this._wrapData(data)), callback);
};
上述代码我们实现了一个saveData方法,它接受一个url作为缓存数据的key,接受一个object的参数data作为保存的value,因为AsyncSorage是无法直接保存object的。所以我们需要将其序列化成json。
a策略提到了数据的有效期,所以我们要给缓存的数据加个时间戳:
/**
* 给数据添加上时间戳
*
* @param {} data 数据
* @returns
* @memberof DataStore
*/
_wrapData(data) {
return {
data: data,
timestamp: new Date().getTime()
}
};
注意:我们取的是本地时间作为时间戳,本地时间存在被纂改的风险,如果条件允许可以取服务器的时间作为时间戳
3.2 获取本地数据
/**
* 获取本地数据
*
* @param {} url 请求地址
* @returns
* @memberof DataStore
*/
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);
}
})
})
};
AsyncStorage.getItem获取的数据是String类型的,以方便使用我们需要将其反序列化成Object
3.3 获取网络数据
/**
* 获取网络数据
*
* @param {} url 请求地址
* @returns
* @memberof DataStore
*/
fetchNetData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
})
.then((responseData) => {
this.saveData(responseData);
resolve(responseData);
})
.catch((error) => {
reject(error);
})
})
}
- 通过上述代码我们获取到网络数据,并对响应不成功的情况抛出了异常
- 在获取到网络数据的同时我们将数据同步到了本地数据库
3.4 实现缓存策略
按照a的策略: 优先从本地获取数据,如果数据过时或不存在则从服务器获取数据,我们需要这样设计我们的代码:
- 我们优先从本地获取数据
- 如果数据存在且在有效期内,我们将数据返回
- 否则我们获取网络数据
/**
* 获取数据,优先获取本地数据,如果无本地数据或本地数据过期则获取网络数据
*
* @param {} url 请求地址
* @returns
* @memberof DataStore
*/
fetchData(url) {
return new Promise((resolve, reject) => {
this.fetchLocalData(url)
.then((wrapData) => {
if (wrapData && DataStore.checkTimestampValid(wrapData.timestamp)) {
resolve(wrapData);
} else {
this.fetchNetData(url)
.then((data) => {
resolve(this._wrapData(data));
})
.catch((error) => {
reject(error);
})
}
})
.catch((error) => {
this.fetchNetData(url)
.then((data) => {
resolve(this._wrapData(data));
})
.catch((error) => {
reject(error);
})
})
})
}
在上述代码中,我们通过DataStore.checkTimestampValid来判断数据是否有效:
/**
* 检查timestamp是否在有效期内
*
* @static
* @param {} timestamp 项目更新时间
* @returns
* @memberof DataStore
*/
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;
return true;
}
以上就是整个缓存策略的实现
React Native之基于AsyncStorage的离线缓存框架设计的更多相关文章
- React-Native(三):React Native是基于React设计的
React Native是基于React js设计的. 参考:<React 入门实例教程> React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript ...
- 基于Spring-Cloud的微服务框架设计
基于Spring-Cloud的微服务框架设计 先进行大的整体的框架整理,然后在针对每一项进行具体的详细介绍
- 房产基于Swoole的PHP RPC框架设计
房产基于Swoole的PHP RPC框架设计 https://mp.weixin.qq.com/s/XSrKEQ-0q4DvjOGTIwYYzg
- react native之封装离线缓存框架
请求数据=>本地有无缓存+缓存数据是否过期 =>可用 =>不可用 将代码封装成一个DataStore.js文件, 这里面主要提供:从本地获取数据,从网络获取数据,创建本地时间戳,请求 ...
- android翻译应用、地图轨迹、视频广告、React Native知乎日报、网络请求框架等源码
Android精选源码 android实现高德地图轨迹效果源码 使用React Native(Android和iOS)实现的 知乎日报效果源码 一款整合百度翻译api跟有道翻译api的翻译君 RxEa ...
- 对比React Native、dcloud、LuaView三个框架技术(内部)
转载自:http://www.jianshu.com/p/ee1cdb33db8d主要对比React Native和5+SDK(就是dcloud的SDK)两个: 开发语言:三个都是用其他语言来统一开发 ...
- react native之使用AsyncStorage 进行数据持久化存储
新建AsncStorageDemoPage.js import React, {Component} from 'react'; import { StyleSheet, View, Text, Bu ...
- 分享基于分布式Http长连接框架--设计模型
追求简单的设计. 也许你的设计功能很强大,但能够在满足你需求的前提下尽量简单明了设计. 当你的设计过于复杂的时候想想是不是有其它路可以走,你站在别人的角度想下,如果别人看了你的设计会不会心领神会,还是 ...
- 基于Web2.0的RIA框架设计与实现
http://www.doc88.com/p-8866851533856.html http://cdmd.cnki.com.cn/Article/CDMD-10614-1012472890.htm
随机推荐
- jquery 学习(七) - 常用动态效果
<!--转载于 听说你的代码很6--><!--http://www.jq22.com/webqd2377--> CSS <style> #content #firs ...
- 「About Blockchain(一)」达沃斯年会上的区块链
「About Blockchain(一)」 --达沃斯年会上的区块链 写在前面:1月23日到26日,在瑞士达沃斯召开了第48届世界经济论坛.这个新闻本没有引起我格外的关注,直到前两天张老师分享给我一篇 ...
- C 语言 register 关键字
register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率.注意是尽可能,不是绝对.你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很 ...
- python日志和异常
“日志”转载:http://www.cnblogs.com/dkblog/archive/2011/08/26/2155018.html "异常"转载:http://www.cnb ...
- Linux内存管理1---内存寻址
1.前言 本文所述关于内存管理的系列文章主要是对陈莉君老师所讲述的内存管理知识讲座的整理. 本讲座主要分三个主题展开对内存管理进行讲解:内存管理的硬件基础.虚拟地址空间的管理.物理地址空间的管理. 本 ...
- Linux 内核里的“智能指针”【转】
转自:http://blog.jobbole.com/88279/ 众所周知,C/C++语言本身并不支持垃圾回收机制,虽然语言本身具有极高的灵活性,但是当遇到大型的项目时,繁琐的内存管理往往让人痛苦异 ...
- David McCullough, Jr.为韦斯利高中毕业生演讲〈你并不特别〉
Dr. Wong, Dr. Keough, Mrs.Novogroski, Ms. Curran, members of the board of education, familyand frien ...
- window系统下远程部署Tomcat
远程访问windows系统,在windows系统上启动tomcat,发布项目.1.拨VPN2.远程桌面连接,cmd --> mstsc 回车,弹出远程桌面连接窗口 3.输入计算机IP:132.2 ...
- igmp组播测试环境搭建
2.4G无线组播测试环境搭建: (1)组播源: VLC 或者 pixstream (2)无线: 2.4G AP (3)客户端PC: VLC播放器 有线直连 无线2.4G PC(组播源pixstream ...
- CentOS 6.5结合busybox完成自制Linux系统及远程登录和nginx安装测试
前言 系统定制在前面的博文中我们就有谈到过了,不过那个裁减制作有简单了点,只是能让系统跑起来而,没有太多的功能,也没的用户登录入口,而这里我们将详细和深入的来谈谈Linux系统的详细定制过程和实 ...