promise实现前端缓存

作者: nick121212 | 来源:发表于2019-12-12 17:27 被阅读0次

    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);
    

    相关文章

      网友评论

        本文标题:promise实现前端缓存

        本文链接:https://www.haomeiwen.com/subject/brqagctx.html