前端接口数据缓存小技巧

1,419 阅读2分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

前言

数据字典相信大家都不陌生,项目中总有一些数据,要是用枚举就面临偶尔改动的问题,要是在数据库中单独用一张表来存,又太浪费了。这就出现了数据字典这个东西。

类似数据字典这类数据并不常变,而且这些数据又经常是用来辅助其他数据的展示。比如说类别,通常后台存的是类别code,但在前台我们要展示的是name。

这类接口呢又不只在一个模块中使用,比如说列表中需要展示类别名,然后点开后再详情里有要展示,查俩次接口确实是能解决问题,但大佬们,我们要有点追求,给后台减点负,我们自己也省点力。

原理说明

既然不查接口,自然数据要做缓存,有缓存就读缓存,没缓存就找接口要。 so easy!

用缓存,我们常用的是localStorage、sessionStorage,其他的 IndexedDB、WebSQL等就不提了。

这里考虑到数据还是有更新的,所以说相对localStorage来说,sessionStorage还是更合理,毕竟sessionStorage网页被关了还是会自动清的。我的项目是vue的,我用的是vuex,因为顾虑到一旦数据发生变动,所有页面展示需要跟着变动。

实现

既然需要做缓存,我们需要在请求外包一层,所以关键逻辑就是这样:

function getDictData(name, isRefresh=false) {
    // 考虑到有强行更新缓存的逻辑, 假设数据存在store里
    if (!isRefresh && store.[name]) {
        return new Promise(function(resolve, reject) { 
            resolve(store[name])
        })
    }
    // 这里通过请求来获取数据, 这里
    return new Promise(function(resolve, reject) { 
        api.getDictData(name).then(res=> {
            // 这里需要一些处理,把数据放到缓存里,所以多包一层
            dispatch('saveDictData', {
                name,
                data: res.data
            })
            resolve(res.data)
        }, (error) => {
            reject(error)
        })
    })
}

这个方法返回的是Promise, 所以大家现有的项目现在改,也非常的简单。直接替换原来的接口请求部分。

(这里就不提供存数据的方法了,相信大家对vuex非常熟悉了,不熟悉的话,可以用sessionStorage)

用的时候可以分俩种了,在不确定数据存储有没有的情况,直接调用getDictData方法;在确定有,比如详情弹窗,就可以使用vuex获取state的方法来获取。

探讨

原来有过在接口拦截的层面做这个缓存想法,通过添加hooks来做,过滤url和参数,只是我们的项目本身在接口拦截这层做了不少事,就没再在这里加这个了。各位可以根据自己的项目试试, 有其他方法也欢迎分享!