溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

原生Javascript怎樣實現(xiàn)一個支持過期時間的DAO庫

發(fā)布時間:2021-09-30 11:30:20 來源:億速云 閱讀:99 作者:柒染 欄目:web開發(fā)

今天就跟大家聊聊有關(guān) 原生Javascript怎樣實現(xiàn)一個支持過期時間的DAO庫,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

主要解決原生localStorage無法設(shè)置過期時間的問題,并通過封裝,來實現(xiàn)一個操作便捷,功能強大的localStorage庫,關(guān)于庫封裝的一些基本思路和模式,我將采用之前寫的如何用不到200行代碼寫一款屬于自己的js類庫中類似的方法。

設(shè)計思路

原生Javascript怎樣實現(xiàn)一個支持過期時間的DAO庫

我們將基于localStorage原始api進行擴展,讓其支持失效時間,操作完成后的回調(diào)。在文章的最后,我將給出庫的完成代碼,接下來我們就一步步實現(xiàn)吧。

正文

首先,我們來設(shè)計庫的基本框架:

const BaseStorage = function(preId, timeSign){   // 初始化一些操作 }  BaseStorage.prototype = {   storage: localStorage || window.localStorage,   set: function(key, value, cb, time){        },   get: function(key, cb){        },   // 刪除storage,如果刪除成功,返回刪除的內(nèi)容   remove: function(key, cb){       } }

如上可以發(fā)現(xiàn),我們的storage會有三個核心api,分別為set,get,remove,我們使用localStorage作為基礎(chǔ)庫支持,當然你也可以將上面的庫換成sessionStorage或者其他。

有了基本骨架,我們就可以實現(xiàn)基本功能的封裝,這里我們先在原型中加一個屬性,來列出數(shù)據(jù)操作中的各個狀態(tài)。

status: {  SUCCESS: 0, // 成功  FAILURE: 1, // 失敗  OVERFLOW: 2, // 數(shù)據(jù)溢出  TIMEOUT: 3  // 超時 },

為了實現(xiàn)過期時間,我們有兩種思路,第一種是先將一個過期時間存到storage中,每次操作都檢查一遍是否過期,但是這種方案意味著對不同的鍵就要設(shè)置不同的過期時間的storage與之對應,這樣會占用額外的庫內(nèi)存,維護起來也不方便。另一種方法就是將過期時間存放到鍵值中,將時間和值通過標識符分隔,每次取的時候從值中截取過期時間,再將真實的值取出來返回,這種方案不會添加額外的鍵值對存儲,維護起來也相對簡單,所以我們采用這種方案。  為了區(qū)分不同的庫對象,我們還可以添加鍵前綴,如下:

const BaseLocalStorage = function(preId, timeSign){    this.preId = preId; // 鍵前綴    this.timeSign = timeSign || '|-|';  // 過期時間和值的分隔符  }

基于這個思想,我們就可以接下來的實現(xiàn)了。

getKey——修飾key的方法,不影響用戶對真實key的影響

getKey: function(key){      return this.preId + key    },

set實現(xiàn)

set: function(key, value, cb, time){      var status = this.status.SUCCESS,      key = this.getKey(key);      // 設(shè)置失效時間,未設(shè)置時間默認為一個月      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;      }      // 操作完成后的回調(diào)      cb && cb.call(this, status, key, value)    }

get實現(xiàn)

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實現(xiàn)

// 刪除storage,如果刪除成功,返回刪除的內(nèi)容    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的實現(xiàn)過程中,由于某種誤操作很可能導致storage報錯,所以建議最好用trycatch包裹,這樣可以避免影響后面的邏輯。

接下來我們可以這么使用:

let a = new BaseStorage('_', '@'); a.set('name', '123') a.get('name') // {status: 0, value: "123"} // 設(shè)置失效時間 a.set('name', '123', null, new Date().getTime() + 1000*60*60*24*31) // 移除 a.remove('name')

完整源碼

/**  * 數(shù)據(jù)管理器  */ (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);       // 設(shè)置失效時間,未設(shè)置時間默認為一個月       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,如果刪除成功,返回刪除的內(nèi)容     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)

看完上述內(nèi)容,你們對 原生Javascript怎樣實現(xiàn)一個支持過期時間的DAO庫有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI