promise实现前端缓存

promise实现前端缓存 举个常见的场景:在调用接口前都需要做一个权限check,伪代码如下。 function getDataFromServer(url, options){ return checkFromServer().then(()=>{ return axios(url,options); }); } function checkFromServer(){ return axios("/check").then((res)=>{ if(res.data.code===403){ throw new Error("permission deny!"); } }); } // 调用接口数据 getDataFromServer("/data",{}); 上面的代码看起来没有什么问题。如果考虑并发状态下呢? getDataFromServer("/data",{}); getDataFromServer("/data1",{}); getDataFromServer("/data3",{}); 在这里会触发三次的/check请求,从实际情况出发的话,在短期内可能只需要一次/check就可以了,性能上也能保障最优。 改造一下上面的代码: const checkPromise = null; function getDataFromServer(url, options){ return checkFromServer().then(()=>{ return axios(url,options); }); } function checkFromServer(){ // 如果有缓存,则直接使用缓存 if(checkPromise){ return checkPromise; } checkPromise = axios("/check").then((res)=>{ if(res.data.code===403){ throw new Error("permission deny!"); } // 5秒后清除缓存 setTimeout(()=>{ checkPromise = null; },5000); }).catch((err)=>{ checkPromise = null; throw err; }); return checkPromise; } // 调用接口数据 getDataFromServer("/data",{}); getDataFromServer("/data1",{}); getDataFromServer("/data3",{}); 如上代码,既解决了/check被调用多次的问题,也解决了并发时候的问题。看起来好像没什么问题了。 再来考虑一个场景把,假设/check数据需要缓存5分钟,5分钟之内都不会再去请求接口并考虑刷新页面的情况呢。 那就比较复杂了,数据可能需要落地到localstorage,可能还需要考虑缓存淘汰机制等情况。 这里有现成写好的库cache-in-stroage。 快速应用: import { cacheDec } from "cache-in-storage"; const getTimeSpan = async (isError = false) => { return new Promise((resolve, reject) => { setTimeout(() => { if (isError) { return reject(new Error("test")); } resolve(Date.now()); }, 200); }); }; // 对getTimeSpan进行缓存,并把缓存结果放入localStorage const getTimeSpanWithCache = cacheDec(getTimeSpan, "keyInCache", { cache:true }, localStorage); // 此时执行方法返回的值都是相同的 getTimeSpanWithCache().then(console.log); getTimeSpanWithCache().then(console.log); getTimeSpanWithCache(true).catch(console.error);

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):