当前位置: 首页 > news >正文

建设网站企业网上银行登录入口美团网站开发形式

建设网站企业网上银行登录入口,美团网站开发形式,防蜘蛛抓取网站代码,哪些网站论坛做推广好问题起因 起因是某次发版之后,服务器接口压力过大,当场宕机,排查之后发现有个接口在首页被调十来次(六七年的老项目了,都是泪呀),后端反馈这个接口的sql很复杂,很耗性能&#xff0c…

问题起因

起因是某次发版之后,服务器接口压力过大,当场宕机,排查之后发现有个接口在首页被调十来次(六七年的老项目了,都是泪呀),后端反馈这个接口的sql很复杂,很耗性能,临时把这个接口放到登录后只执行一次,数据缓存在 localStorage 内,后续这个接口都直接从 localStorage 中取。

虽然临时解决了宕机问题,但还是会有多个组件内同时发起多个相同请求的问题。现在也有很多请求库带有缓存功能,但是这是老项目,请求只封装了 axios ,换个请求库风险又很高,最终决定自己搞搞。

思路历程

当时最初的想法就是在 axios 拦截器内做判断,首先在 interceptors.request 中判断缓存中是否有对应的请求,在 interceptors.response 中赋予缓存设置。

但很快问题就来,在 interceptors.request 判断有缓存之后,再取消这个缓存吗?搞了搞又发现个问题,当某个请求已发起,但是还没返回,这个时候这个请求又发起了,这不没解决问题。

然后又想着在 interceptors.request 中先让请求占位,这样多个组件同时发起某个请求,只要第一个占位了,后续的都取消。问题又来了,后续请求取消之后,后续逻辑又不触发了。后面突然想到我可以在请求之前做检测,当对应接口已经在缓存中时,就直接返回当前缓存中的值,缓存不存在再发起,这个时候肯定会想那第一个已经发起的还未返回的,后续相同接口从缓存中拿到的值如何出发后续逻辑呢?

请求本身返回的是 promise,那我先把 promise 存入缓存,相同接口再请求时直接返回缓存中的 promise ,这样后续逻辑可以正常触发。

最终方案

最终实现如下(仅 get 请求做接口缓存):

export function get<T = any>(url: string, config: AxiosRequestConfig = {}): Promise<T> {const curHttpCacheKey: string = configToKey({url,...config})if (!httpCache.hasCache(curHttpCacheKey)) {const httpRequest = instance.get(url, config)httpCache.setCache(curHttpCacheKey, httpRequest)return httpRequest as Promise<T>} else {return Promise.resolve(httpCache.getCache(curHttpCacheKey))}
}

get 请求再做个封装,缓存中以请求链接和 query拼接的字符串作为 keyhttpCache 后续会讲, configToKey 实现如下:

export function configToKey(config: AxiosRequestConfig): string {let key = config.url as stringif (config.params) {key += JSON.stringify(config.params)}return key
}

然后在 interceptors.response 中赋予缓存值:

instance.interceptors.response.use((response) => {if (response.status === 200 && response.config.method === 'get') {const curHttpCacheKey = configToKey(response.config)// 缓存中设置的值要和下面 return 的结果一致httpCache.setCache(curHttpCacheKey, response)}return response},(error) => {return Promise.reject(error)}
)

下面说下 httpCache

import CacheMemory from 'f-cache-memory'const httpCache = new CacheMemory()
export default httpCache

缓存库 f-cache-memory

初始化一个库就行了,f-cache-memory 就是我专门开发的库,底层用的 map ,有些API也贴近 map,API如下:

初始化参数

参数默认值描述版本
size?: number100最多缓存多少个
expiration?: numberNumber.MAX_SAFE_INTEGER按时间毫秒设置缓存有效期,超出时间会被删除
change?: (data: [string, any][]) => void-当缓存变更的时候,可以在此方法内同步外部数据新增于 v0.0.7

api

名称参数返回值类型描述版本
initCachedata: [string, any][]-初始化缓存数据新增于 v0.0.7
hasCachekey: stringboolean验证是否在缓存中
setCachekey: string, data: any, expiration?: number-设置缓存,expiration 以毫秒为单位设置缓存有效期,优先级高于初始化的 expiration 参数,未设置时默认为 初始化的 expirationexpiration 新增于 v0.0.3
getCachekey: stringany获取缓存
deleteCachekey: string-删除缓存
deleteCacheByStartsurl: string-根据键值的前缀删除缓存
clearCache--清空缓存
cacheSize-number有多少个缓存
getNowCache-any获取当前缓存,默认为最后一个,getPreviousCache/getNextCache/goPostionCache/goAbsPostionCache都会影响当前缓存的值
getPreviousCache-any按设置顺序前一个缓存
getNextCache-any按设置顺序后一个缓存
goPostionCachenum: numberany相对当前缓存获取缓存,1为后一个,-1为前一个
goAbsPostionCachenum: numberany按照设置顺序获取第 num 个缓存
getCacheToArrayneedTime: boolean = false[string, any][]按设置顺序转换为数组,如果参数为 false,则直接返回设置的数据,如果为 true,则会返回 { dateTime: 过期时间, data: 设置数据 }dateTime 参数新增于 v0.0.7

同步缓存内外数据

当我们希望缓存内的数据和缓存外联动时,我们可以初始化时传入 第三个参数 change 函数, change 函数的参数就是缓存内的数据(内部数据的结构是 { dateTime: 过期时间, data: 设置的缓存 }),所以如果与 localStorage 联动如下:

const localCache = new CacheMemory(100, 100000, (data) => {localStorage.setItem('localCache', JSON.stringify(data))
})
localCache.setCache('aaa', 111)
localCache.setCache('bbb', 222)

那下次再打开浏览器,localStorage 内的值如何传递到缓存中,此时可以初始化之后使用 initCache :

const initCache = new CacheMemory()
const localStorageCache = localStorage.getItem('localCache')
if (localStorageCache) {initCache.initCache(JSON.parse(localStorageCache))
}
console.log(initCache.getCacheToArray())

Vue:

const cacheList = ref<[string, any][]>([])
const localCache = new CacheMemory(100, 100000, (data) => {cacheList.value = data
})

React:

const [cacheList, setCacheList] = useState<[string, any][]>([])
const localCache = new CacheMemory(100, 100000, (data) => {setCacheList(data)
})

实际上面还有个问题,就是添加缓存之后,什么时候使缓存失效,虽然有过期时间一说,但设的小了,缓存没效果,设得大了,就涉及需要清缓存。

这里我提供几个思路:

  1. 过期时间设的小一点,仅保证多个组件同时加载接口时做到缓存;
  2. 接口映射表,哪些接口改变之后需要清缓存,做好映射关系,在 interceptors.response 中清除对应缓存,这样项目中的代码不用动;
  3. 如果项目完全采用的 REST API 风格,可以在 post/put/delete 中清除对应缓存,此处有个 例子。

最后我们采用了第一种思路,解决服务器临时压力,因为接口规范不统一,接口映射表又太多,一时难以保证齐全。

完整例子可以查看 vue-components ,本地运行,接口 mock 。

http://www.yayakq.cn/news/432297/

相关文章:

  • 做网站江西外贸建站行业好做吗
  • 做网站含营销导航网站 win8风格
  • 网站制作推广需要多少钱手工艺品网站建设方案
  • 网站公司企业宗旨网站建设实训个人总结1000字
  • 替朋友做网站厦门网站设计培训公司
  • 贵州省住房和建设厅网网站wordpress软件分享
  • 怎么查那些人输入做网站广州seo团队
  • 金坛做网站365网站
  • 如何用百度上传图片做网站外链frontpage做网站
  • 东莞网站建设员微网站开发案例
  • 企业网站建设如何去规划网页版qq安全中心登录入口
  • django做企业级网站学校校园网站建设服务
  • 无锡网站制作高端网站优化心得
  • 制作介绍的网站模板做瞹网站
  • 网站模板之家免费下载建设信用卡分期购物网站
  • 什么是网站前台电商推广和网络推广的区别
  • 网站站内链接怎么做wordpress标签扩展
  • 网网站建设与设计郑州网站建设找三牛
  • 信丰做网站重庆网站制作设计获客
  • 中山网站建设的公司查询一个网站是用什么系统做的
  • 灯具公司网站模板广告网站建设制作设计服务商
  • 新企业如何在国税网站上做套餐专业网页制作软件都能帮助用户组织和管理
  • 网站怎么对接微信支付宝wordpress编辑慢
  • 网站后来功能重庆企业免费建站
  • 点网站建设做360网站优化快速排
  • 做四级题目的网站网页编辑软件哪个好
  • 四川住房和城乡建设厅网站主页南宁企业网站设计
  • 网站psd下载悟空建站seo服务
  • 网站需要更新的频率一站式服务logo设计
  • 网站空间备份wordpress 轮播插件