如何实现90秒窗口期内禁止调用Reporting API,改用缓存数据?
解决Reporting API 90秒调用限制的缓存策略
这个需求其实很常见,核心就是跟踪API调用的时间戳,再结合缓存机制来做判断。不管你用什么开发平台(Web、iOS、Android等),底层逻辑都是通用的,我给你一步步拆解实现思路:
核心步骤
1. 持久化存储上次API调用的时间戳
你需要一个能跨应用启动保存数据的地方,用来记录最后一次调用API的时间:
- Web端:用
localStorage或者sessionStorage(如果只需要会话内有效) - iOS:用
UserDefaults或者Keychain(敏感数据用后者) - Android:用
SharedPreferences或者DataStore - 后端服务:用Redis、数据库或者内存缓存(如果是后端调用的话)
举个Web端的例子,存储时间戳:
localStorage.setItem('lastAPICallTime', Date.now().toString());
2. 计算时间差并判断是否允许调用API
每次应用打开时,先取出上次的调用时间,和当前时间计算差值,判断是否满足90秒的限制:
const now = Date.now(); const lastCallTime = Number(localStorage.getItem('lastAPICallTime')) || 0; const isAllowed = now - lastCallTime >= 90 * 1000; // 转换成毫秒
3. 分支逻辑处理
根据上面的判断结果,走不同的流程:
- 允许调用API:发起请求获取最新数据,更新缓存和时间戳,然后展示新数据
- 不允许调用API:直接读取缓存的数据展示给用户
- 特殊情况:首次打开应用时,没有时间戳和缓存,直接调用API即可
4. 缓存数据的管理
和时间戳一起,把API返回的数据也存在同一个持久化存储里。比如Web端存储缓存:
localStorage.setItem('reportAPICache', JSON.stringify(apiResponseData));
读取缓存时:
const cachedData = JSON.parse(localStorage.getItem('reportAPICache'));
完整代码示例(Web端)
这里给你封装一个可复用的函数,包含错误处理和降级逻辑:
async function getReportData() { const now = Date.now(); const lastCallTime = Number(localStorage.getItem('lastAPICallTime')) || 0; const cachedData = localStorage.getItem('reportAPICache'); // 判断是否满足调用条件 if (now - lastCallTime >= 90 * 1000) { try { // 调用API const response = await fetch('https://your-reporting-api-endpoint.com/data'); if (!response.ok) throw new Error('API请求失败'); const freshData = await response.json(); // 更新缓存和时间戳 localStorage.setItem('reportAPICache', JSON.stringify(freshData)); localStorage.setItem('lastAPICallTime', now.toString()); return freshData; } catch (error) { console.error('获取最新数据失败,使用缓存:', error); // API调用失败时,降级使用缓存(如果存在) if (cachedData) return JSON.parse(cachedData); // 缓存也不存在的话,抛出错误让上层处理 throw new Error('无缓存且API请求失败'); } } else { // 未到时间,返回缓存数据 if (cachedData) { console.log('使用缓存数据'); return JSON.parse(cachedData); } else { // 首次打开,直接调用API console.log('首次打开,调用API'); const response = await fetch('https://your-reporting-api-endpoint.com/data'); const freshData = await response.json(); localStorage.setItem('reportAPICache', JSON.stringify(freshData)); localStorage.setItem('lastAPICallTime', now.toString()); return freshData; } } } // 应用启动时调用 getReportData() .then(data => { // 渲染数据到页面 renderReport(data); }) .catch(error => { // 处理错误,比如显示提示 showError(error.message); });
额外注意事项
- 数据安全性:如果API返回的数据包含敏感信息,不要用普通的明文存储(比如
localStorage、UserDefaults),要用加密存储方案 - 时间篡改问题:如果用户修改设备系统时间,可能导致时间差判断出错。如果要处理这个边缘情况,可以在API返回时带上服务器时间,用服务器时间来记录上次调用时间,而不是本地时间
- 缓存过期:除了90秒的调用限制,你也可以根据业务需求给缓存设置额外的过期时间,确保用户不会看到太久远的数据
内容的提问来源于stack exchange,提问作者nacho sepulveda
相关产品推荐
相关产品推荐

