今天就跟大家聊聊有關(guān) 原生Javascript怎樣實現(xiàn)一個支持過期時間的DAO庫,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、網(wǎng)站設(shè)計、外貿(mào)網(wǎng)站建設(shè)、庫爾勒網(wǎng)絡(luò)推廣、微信小程序開發(fā)、庫爾勒網(wǎng)絡(luò)營銷、庫爾勒企業(yè)策劃、庫爾勒品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供庫爾勒建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
主要解決原生localStorage無法設(shè)置過期時間的問題,并通過封裝,來實現(xiàn)一個操作便捷,功能強(qiáng)大的localStorage庫,關(guān)于庫封裝的一些基本思路和模式,我將采用之前寫的如何用不到200行代碼寫一款屬于自己的js類庫中類似的方法。
設(shè)計思路
我們將基于localStorage原始api進(jìn)行擴(kuò)展,讓其支持失效時間,操作完成后的回調(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ǔ)庫支持,當(dāng)然你也可以將上面的庫換成sessionStorage或者其他。
有了基本骨架,我們就可以實現(xiàn)基本功能的封裝,這里我們先在原型中加一個屬性,來列出數(shù)據(jù)操作中的各個狀態(tài)。
status: { SUCCESS: 0, // 成功 FAILURE: 1, // 失敗 OVERFLOW: 2, // 數(shù)據(jù)溢出 TIMEOUT: 3 // 超時 },
為了實現(xiàn)過期時間,我們有兩種思路,第一種是先將一個過期時間存到storage中,每次操作都檢查一遍是否過期,但是這種方案意味著對不同的鍵就要設(shè)置不同的過期時間的storage與之對應(yīng),這樣會占用額外的庫內(nèi)存,維護(hù)起來也不方便。另一種方法就是將過期時間存放到鍵值中,將時間和值通過標(biāo)識符分隔,每次取的時候從值中截取過期時間,再將真實的值取出來返回,這種方案不會添加額外的鍵值對存儲,維護(hù)起來也相對簡單,所以我們采用這種方案。 為了區(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è)置時間默認(rèn)為一個月 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)過程中,由于某種誤操作很可能導(dǎo)致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è)置時間默認(rèn)為一個月 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庫有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。