面试题答案
一键面试缓存时机
- 首次请求:在组件挂载时,发起商品列表请求,若缓存中不存在数据,则正常请求服务器,并将返回的数据存入缓存。
- 后续请求:在组件再次渲染需要获取商品列表数据时,先检查缓存是否存在且未过期,若满足条件则直接使用缓存数据,避免重复请求服务器。
缓存存储方式
- 内存缓存:
- 优势:适用于单页面应用中,在当前页面生命周期内数据的快速访问。数据存储在JavaScript的变量中,访问速度极快。例如在Vue组件内定义一个data属性来存储缓存数据,如
data() { return { productListCache: null } }
。 - 劣势:页面刷新或关闭后数据丢失。
- 优势:适用于单页面应用中,在当前页面生命周期内数据的快速访问。数据存储在JavaScript的变量中,访问速度极快。例如在Vue组件内定义一个data属性来存储缓存数据,如
- localStorage:
- 优势:数据持久化存储,关闭页面或浏览器后数据依然存在,适合缓存不经常变化且需要长期存储的数据。例如商品分类列表等相对稳定的数据。
- 劣势:容量有限(一般约5MB),且只能存储字符串类型数据,需要对存入的数据进行JSON.stringify序列化,取出时进行JSON.parse反序列化。
- sessionStorage:
- 优势:在当前会话(浏览器标签页打开到关闭)内有效,数据不会像localStorage那样长期保存,且容量与localStorage相近。适合缓存一些仅在当前页面会话期间需要的数据,如用户在当前页面浏览的商品列表。
- 劣势:同样只能存储字符串类型数据,需要进行序列化和反序列化操作,且标签页关闭后数据丢失。
在实际应用中,可以结合使用。例如,对于短期内频繁请求且希望快速响应的数据,优先使用内存缓存;对于相对稳定且希望持久化存储的数据,使用localStorage;对于只在当前会话有效的数据,使用sessionStorage。
缓存过期处理
- 添加过期时间标识:在缓存数据时,同时记录数据的过期时间。例如,在存入缓存数据时,给数据对象添加一个
expireTime
属性,记录当前时间加上过期时长(如const cacheData = { productList: response.data, expireTime: new Date().getTime() + 60 * 1000 }
,这里设置过期时长为1分钟)。 - 每次读取缓存时检查过期时间:在从缓存中获取数据时,先判断当前时间是否超过
expireTime
。如果超过,则认为缓存过期,清除缓存数据,并重新发起网络请求。例如:
const cacheData = localStorage.getItem('productListCache');
if (cacheData) {
const { productList, expireTime } = JSON.parse(cacheData);
if (new Date().getTime() < expireTime) {
// 未过期,使用缓存数据
this.productList = productList;
} else {
// 过期,清除缓存
localStorage.removeItem('productListCache');
// 重新请求数据
this.fetchProductList();
}
} else {
// 缓存不存在,重新请求数据
this.fetchProductList();
}
数据更新处理
- 监听数据更新操作:在商品数据发生更新的地方(如商品添加、删除、修改操作的接口响应后),及时更新缓存数据。例如,当添加新商品成功后,不仅要更新页面展示的数据,也要更新缓存中的商品列表数据。
- 主动失效缓存:对于一些无法实时感知数据更新的情况,可以设置一个较短的缓存过期时间,确保数据不会长时间使用旧的缓存。或者在某些特定操作后(如用户手动点击“刷新”按钮),主动清除相关缓存,重新请求最新数据。例如:
// 点击刷新按钮清除缓存并重新请求
refreshProductList() {
localStorage.removeItem('productListCache');
this.fetchProductList();
}