新聞中心
本文主要解決原生localStorage無法設(shè)置過期時(shí)間的問題,并通過封裝,來實(shí)現(xiàn)一個(gè)操作便捷,功能強(qiáng)大的localStorage庫,關(guān)于庫封裝的一些基本思路和模式,我將采用之前寫的如何用不到200行代碼寫一款屬于自己的js類庫中類似的方法,感興趣的朋友可以學(xué)習(xí),交流。

成都創(chuàng)新互聯(lián)主營芙蓉網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,app軟件開發(fā)公司,芙蓉h5微信平臺(tái)小程序開發(fā)搭建,芙蓉網(wǎng)站營銷推廣歡迎芙蓉等地區(qū)企業(yè)咨詢
設(shè)計(jì)思路
我們將基于localStorage原始api進(jìn)行擴(kuò)展,讓其支持失效時(shí)間,操作完成后的回調(diào)。在文章的最后,我將給出庫的完成代碼,接下來我們就一步步實(shí)現(xiàn)吧。
正文
首先,我們來設(shè)計(jì)庫的基本框架:
- 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會(huì)有三個(gè)核心api,分別為set,get,remove,我們使用localStorage作為基礎(chǔ)庫支持,當(dāng)然你也可以將上面的庫換成sessionStorage或者其他。
有了基本骨架,我們就可以實(shí)現(xiàn)基本功能的封裝,這里我們先在原型中加一個(gè)屬性,來列出數(shù)據(jù)操作中的各個(gè)狀態(tài)。
- status: {
- SUCCESS: 0, // 成功
- FAILURE: 1, // 失敗
- OVERFLOW: 2, // 數(shù)據(jù)溢出
- TIMEOUT: 3 // 超時(shí)
- },
為了實(shí)現(xiàn)過期時(shí)間,我們有兩種思路,第一種是先將一個(gè)過期時(shí)間存到storage中,每次操作都檢查一遍是否過期,但是這種方案意味著對(duì)不同的鍵就要設(shè)置不同的過期時(shí)間的storage與之對(duì)應(yīng),這樣會(huì)占用額外的庫內(nèi)存,維護(hù)起來也不方便。另一種方法就是將過期時(shí)間存放到鍵值中,將時(shí)間和值通過標(biāo)識(shí)符分隔,每次取的時(shí)候從值中截取過期時(shí)間,再將真實(shí)的值取出來返回,這種方案不會(huì)添加額外的鍵值對(duì)存儲(chǔ),維護(hù)起來也相對(duì)簡單,所以我們采用這種方案。 為了區(qū)分不同的庫對(duì)象,我們還可以添加鍵前綴,如下:
- const BaseLocalStorage = function(preId, timeSign){
- this.preId = preId; // 鍵前綴
- this.timeSign = timeSign || '|-|'; // 過期時(shí)間和值的分隔符
- }
基于這個(gè)思想,我們就可以接下來的實(shí)現(xiàn)了。
getKey——修飾key的方法,不影響用戶對(duì)真實(shí)key的影響
- getKey: function(key){
- return this.preId + key
- },
set實(shí)現(xiàn)
- set: function(key, value, cb, time){
- var status = this.status.SUCCESS,
- key = this.getKey(key);
- // 設(shè)置失效時(shí)間,未設(shè)置時(shí)間默認(rèn)為一個(gè)月
- 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實(shí)現(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實(shí)現(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的實(shí)現(xiàn)過程中,由于某種誤操作很可能導(dǎo)致storage報(bào)錯(cuò),所以建議最好用trycatch包裹,這樣可以避免影響后面的邏輯。
接下來我們可以這么使用:
- let a = new BaseStorage('_', '@');
- a.set('name', '123')
- a.get('name') // {status: 0, value: "123"}
- // 設(shè)置失效時(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í)間,未設(shè)置時(shí)間默認(rèn)為一個(gè)月
- 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)
網(wǎng)站題目:面向?qū)ο缶幊?原生Javascript實(shí)現(xiàn)一個(gè)支持過期時(shí)間的DAO庫
網(wǎng)站鏈接:http://www.5511xx.com/article/cddegse.html


咨詢
建站咨詢
