App往往都有缓存功能,例如常见的新闻类应用,如果你关闭网络,你上次打开App加载的数据还在,只是不能加载新的数据了。
我的博客,欢迎前来尬聊。
集中处理请求
如果你fetch数据的页面有多个,不集中处理的话每个页面都要单独进行缓存处理。那么,如何对http请求进行集中处理?
在WebApp中常见的做法就是将请求放在action
里面,例如Vuex
和Redux
。但是在业务逻辑较少的App中,我们往往可能不需要Redux
。这时就需要我们自己对集中请求进行封装。 封装AsyncStorage
AsyncStorage只能存取字符串,我们需封装一下,让它能存取json
:
import { AsyncStorage } from 'react-native'class Storage { set({key, val}) { return AsyncStorage.setItem(key, JSON.stringify(val)) } get(key) { return AsyncStorage.getItem(key).then(val => { return JSON.parse(val) }) } remove(key) { return AsyncStorage.removeItem(key) } clear() { return AsyncStorage.clear() }}export default new Storage()
命名为storage.js
封装公共请求函数
在网络故障时获取storage里的内容,网络良好时更新storage。
import axios from 'axios'import storage from './storage'import apiList from './apiList'import {NetInfo, ToastAndroid} from 'react-native'/** * @param {String} api 接口名称 * @param {Object} [replace={}] 替换url中的{}包裹的参数 * @param {Object} [data={}] 传给服务端的数据 * @param {Object} [headers={}] http请求头参数 * @return {Promise} 返回promise */const $http = async ({api, replace, data, headers}) => { let regExp = /\{ *([\w_\-]+) *\}/g, url = apiList[api].url, replaceList = url.match(regExp) if(replaceList) { replaceList.forEach(i => { let key = i.slice(1, i.length - 1) url = url.replace(i, replace[key]) }) } let netStatu = await NetInfo.getConnectionInfo() let result if(['none', 'unknown'].includes(netStatu.type)) { ToastAndroid.show('请检查您的网络连接', ToastAndroid.SHORT) result = await storage.get(api) || null } else { try { let {data} = await axios({ method: apiList[api].method, url: url, data: data, headers: headers }) result = data } catch(err) { ToastAndroid.show(err.message, ToastAndroid.SHORT) result = await storage.get(api) || null } await storage.set({ key: api, val: result }) } return result}export default $http
命名为service.js
请求配置
为标示请求唯一性,我们需给每个请求取一个名称:
export default { GET_NEWS_LIST: { url: '/my/news?pageNum={pageNum}&pageSize={pageSize}', method: 'get' }}
命名为apiList.js
请求调用
我们可以模仿一下Vuex
或Redux
的action:
import $http from './service'export async function getNewsList(pageNum, pageSize) { return await $http({ api: 'GET_NEWS_LIST', replace: { pageNum, pageSize } })}
命名为serviceAction.js
import {getNewsList} from './serviceAction'// ...async componentDidMount() { let newsList = await getNewsList(1) this.setState({ newsList })}// ...
原文地址: