Javascript从入门到精通——面向对象编程: 原生Javascript实现一个支持过期时间的DAO库
小职 2020-12-18 来源 : 阅读 600 评论 0

摘要:本篇主要介绍了面向对象编程: 原生Javascript实现一个支持过期时间的DAO库,希望对前端Javascript的学习有所帮助。

本篇主要介绍了面向对象编程: 原生Javascript实现一个支持过期时间的DAO库,希望对前端Javascript的学习有所帮助。

Javascript从入门到精通——面向对象编程: 原生Javascript实现一个支持过期时间的DAO库


本文主要解决原生localStorage无法设置过期时间的问题,并通过封装,来实现一个操作便捷,功能强大的localStorage库,关于库封装的一些基本思路和模式,我将采用之前写的如何用不到200行代码写一款属于自己的js类库中类似的方法,感兴趣的朋友可以学习,交流。

 

设计思路

 Javascript从入门到精通——面向对象编程: 原生Javascript实现一个支持过期时间的DAO库

 

我们将基于localStorage原始api进行扩展,让其支持失效时间,操作完成后的回调。在文章的最后,我将给出库的完成代码,接下来我们就一步步实现吧。

 

正文

 

首先,我们来设计库的基本框架:

 

const BaseStorage = function(preId, timeSign){

  // 初始化一些操作

}

 

BaseStorage.prototype = {

  storage: localStorage || window.localStorage,

  set: function(key, value, cb, time){

     

  },

  get: function(key, cb){

     

  },

  // 删除storage,如果删除成功,返回删除的内容

  remove: function(key, cb){

    

  }

}

如上可以发现,我们的storage会有三个核心api,分别为set,get,remove,我们使用localStorage作为基础库支持,当然你也可以将上面的库换成sessionStorage或者其他。

 

有了基本骨架,我们就可以实现基本功能的封装,这里我们先在原型中加一个属性,来列出数据操作中的各个状态。

 

status: {

 SUCCESS: 0, // 成功

 FAILURE: 1, // 失败

 OVERFLOW: 2, // 数据溢出

 TIMEOUT: 3  // 超时

},

为了实现过期时间,我们有两种思路,第一种是先将一个过期时间存到storage中,每次操作都检查一遍是否过期,但是这种方案意味着对不同的键就要设置不同的过期时间的storage与之对应,这样会占用额外的库内存,维护起来也不方便。另一种方法就是将过期时间存放到键值中,将时间和值通过标识符分隔,每次取的时候从值中截取过期时间,再将真实的值取出来返回,这种方案不会添加额外的键值对存储,维护起来也相对简单,所以我们采用这种方案。 为了区分不同的库对象,我们还可以添加键前缀,如下:

 

const BaseLocalStorage = function(preId, timeSign){

   this.preId = preId; // 键前缀

   this.timeSign = timeSign || '|-|';  // 过期时间和值的分隔符

 }

基于这个思想,我们就可以接下来的实现了。

 

getKey——修饰key的方法,不影响用户对真实key的影响

 

getKey: function(key){

     return this.preId + key

   },

set实现

 

set: function(key, value, cb, time){

     var status = this.status.SUCCESS,

     key = this.getKey(key);

     // 设置失效时间,未设置时间默认为一个月

     try{

       time = new Date(time).getTime() || time.getTime();

     }catch(e){

       time = new Date().getTime() + 1000*60*60*24*31

     }

     try{

       this.storage.setItem(key, time + this.timeSign + value);

     }catch(e){

       status = this.status.OVERFLOW;

     }

     // 操作完成后的回调

     cb && cb.call(this, status, key, value)

   }

get实现

 

get: function(key, cb){

     var status = this.status.SUCCESS,

     key = this.getKey(key),

     value = null,

     timeSignLen = this.timeSign.length,

     that = this,

     index,

     time,

     result;

     try{

       value = that.storage.getItem(key);

     }catch(e){

       result = {

         status: that.status.FAILURE,

         value: null

       }

       cb && cb.call(this, result.status, result.value);

       return result

     }

     if(value) {

       index = value.indexOf(that.timeSign);

       time = +value.slice(0, index);

       // 判断是否过期,过期则清除

       if(time > new Date().getTime() || time == 0){

         value = value.slice(index+timeSignLen);

       }else{

         value = null,

         status = that.status.TIMEOUT;

         that.remove(key);

       }

     }else{

       status = that.status.FAILURE;

     }

     result = {

       status: status,

       value: value

     };

     cb && cb.call(this, result.status, result.value);

     return result

   }

remove实现

 

// 删除storage,如果删除成功,返回删除的内容

   remove: function(key, cb){

     var status = this.status.FAILURE,

     key = this.getKey(key),

     value = null;

     try{

       value = this.storage.getItem(key);

     }catch(e){

       // dosomething

     }

     if(value){

       try{

         this.storage.removeItem(key);

         status = this.status.SUCCESS;

       }catch(e){

         // dosomething

       }

     }

     cb && cb.call(this, status, status > 0 ? null : value.slice(value.indexOf(this.timeSign) + this.timeSign.length))

   }

在api的实现过程中,由于某种误操作很可能导致storage报错,所以建议最好用trycatch包裹,这样可以避免影响后面的逻辑。

 

接下来我们可以这么使用:

 

let a = new BaseStorage('_', '@');

a.set('name', '123')

a.get('name') // {status: 0, value: "123"}

// 设置失效时间

a.set('name', '123', null, new Date().getTime() + 1000*60*60*24*31)

// 移除

a.remove('name')

完整源码

 

/**

 * 数据管理器

 */

(function(win){

  const BaseStorage = function(preId, timeSign){

    this.preId = preId;

    this.timeSign = timeSign || '|-|';

  }

  

  BaseStorage.prototype = {

    status: {

      SUCCESS: 0,

      FAILURE: 1,

      OVERFLOW: 2,

      TIMEOUT: 3

    },

    storage: localStorage || window.localStorage,

    getKey: function(key){

      return this.preId + key

    },

    set: function(key, value, cb, time){

      var status = this.status.SUCCESS,

      key = this.getKey(key);

      // 设置失效时间,未设置时间默认为一个月

      try{

        time = new Date(time).getTime() || time.getTime();

      }catch(e){

        time = new Date().getTime() + 1000*60*60*24*31

      }

      try{

        this.storage.setItem(key, time + this.timeSign + value);

      }catch(e){

        status = this.status.OVERFLOW;

      }

      cb && cb.call(this, status, key, value)

    },

    get: function(key, cb){

      var status = this.status.SUCCESS,

      key = this.getKey(key),

      value = null,

      timeSignLen = this.timeSign.length,

      that = this,

      index,

      time,

      result;

      try{

        value = that.storage.getItem(key);

      }catch(e){

        result = {

          status: that.status.FAILURE,

          value: null

        }

        cb && cb.call(this, result.status, result.value);

        return result

      }

      if(value) {

        index = value.indexOf(that.timeSign);

        time = +value.slice(0, index);

        if(time > new Date().getTime() || time == 0){

          value = value.slice(index+timeSignLen);

        }else{

          value = null,

          status = that.status.TIMEOUT;

          that.remove(key);

        }

      }else{

        status = that.status.FAILURE;

      }

      result = {

        status: status,

        value: value

      };

      cb && cb.call(this, result.status, result.value);

      return result

    },

    // 删除storage,如果删除成功,返回删除的内容

    remove: function(key, cb){

      var status = this.status.FAILURE,

      key = this.getKey(key),

      value = null;

      try{

        value = this.storage.getItem(key);

      }catch(e){

        // dosomething

      }

      if(value){

        try{

          this.storage.removeItem(key);

          status = this.status.SUCCESS;

        }catch(e){

          // dosomething

        }

      }

      cb && cb.call(this, status, status > 0 ? null : value.slice(value.indexOf(this.timeSign) + this.timeSign.length))

    }

  }

  

  win.BS = BaseStorage;

})(window)

  



关注“职坐标在线”(Zhizuobiao_Online)公众号,免费获取学习视频资料、技术就业咨询。

Javascript从入门到精通——面向对象编程: 原生Javascript实现一个支持过期时间的DAO库

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程