1. 程式人生 > >運用惰性刪除和定時刪除實現可過期的localStorage快取

運用惰性刪除和定時刪除實現可過期的localStorage快取

### localStorage簡介 使用localStorage可以在瀏覽器中儲存鍵值對的資料。經常被和localStorage一併提及的是sessionStorage,它們都可以在當瀏覽器中儲存鍵值對的資料。但是它們之間的區別是:儲存在localStorage的資料可以長期保留;而當頁面會話結束(也就是當頁面被關閉)時,儲存在sessionStorage的資料會被清除。 另外需要注意的是,localStorage中的鍵值對總是以字串的形式儲存,並且只能訪問當前域名下的資料,不能跨域名訪問。 歡迎關注微信公眾號:萬貓學社,每週一分享Java技術乾貨。 ### localStorage方法 可以通過`setItem`方法增加了一個鍵值對資料,比如: ```javascript localStorage.setItem('name', 'OneMore'); ``` 如果該鍵已經存在,那麼該鍵對應的值將被覆蓋。還可以使用`getItem`方法讀取對應鍵的值資料,比如: ```javascript var name = localStorage.getItem('name'); ``` 可以使用`removeItem`方法移除對應的鍵,比如: ```javascript localStorage.removeItem('name'); ``` 也可以使用`clear`方法移除當前域名下所有的鍵值對資料,比如: ```javascript localStorage.clear(); ``` 歡迎關注微信公眾號:萬貓學社
,每週一分享Java技術乾貨。 ### 可過期的localStorage快取 正如上面所提到的,localStorage只能用於長久儲存整個網站的資料,儲存的資料沒有過期時間,直到手動去刪除。所以要實現可過期的localStorage快取的中重點就是:如何清理過期的快取? ### 惰性刪除 惰性刪除是指,某個鍵值過期後,該鍵值不會被馬上刪除,而是等到下次被使用的時候,才會被檢查到過期,此時才能得到刪除。我們先來簡單實現一下: ```javascript var lsc = (function (self) { var prefix = 'one_more_lsc_' /** * 增加一個鍵值對資料 * @param key 鍵 * @param val 值 * @param expires 過期時間,單位為秒 */ self.set = function (key, val, expires) { key = prefix + key; val = JSON.stringify({'val': val, 'expires': new Date().getTime() + expires * 1000}); localStorage.setItem(key, val); }; /** * 讀取對應鍵的值資料 * @param key 鍵 * @returns {null|*} 對應鍵的值 */ self.get = function (key) { key = prefix + key; var val = localStorage.getItem(key); if (!val) { return null; } val = JSON.parse(val); if (val.expires < new Date().getTime()) { localStorage.removeItem(key); return null; } return val.val; }; return self; }(lsc || {})); ``` 上述程式碼通過惰性刪除已經實現了可過期的localStorage快取,但是也有比較明顯的缺點:如果一個key一直沒有被用到,即使它已經過期了也永遠存放在localStorage。為了彌補這樣缺點,我們引入另一種清理過期快取的策略。 歡迎關注微信公眾號:萬貓學社
,每週一分享Java技術乾貨。 ### 定時刪除 定時刪除是指,每隔一段時間執行一次刪除操作,並通過限制刪除操作執行的次數和頻率,來減少刪除操作對CPU的長期佔用。另一方面定時刪除也有效的減少了因惰性刪除帶來的對localStorage空間的浪費。 每隔一秒執行一次定時刪除,操作如下: 1. 隨機測試20個設定了過期時間的key。 2. 刪除所有發現的已過期的key。 3. 若刪除的key超過5個則重複**步驟1**,直至重複500次。 具體實現如下: ```javascript var lsc = (function (self) { var prefix = 'one_more_lsc_' var list = []; //初始化list self.init = function () { var keys = Object.keys(localStorage); var reg = new RegExp('^' + prefix); var temp = []; //遍歷所有localStorage中的所有key for (var i = 0; i < keys.length; i++) { //找出可過期快取的key if (reg.test(keys[i])) { temp.push(keys[i]); } } list = temp; }; self.init(); self.check = function () { if (!list || list.length == 0) { return; } var checkCount = 0; while (checkCount < 500) { var expireCount = 0; //隨機測試20個設定了過期時間的key for (var i = 0; i < 20; i++) { if (list.length == 0) { break; } var index = Math.floor(Math.random() * list.length); var key = list[index]; var val = localStorage.getItem(list[index]); //從list中刪除被惰性刪除的key if (!val) { list.splice(index, 1); expireCount++; continue; } val = JSON.parse(val); //刪除所有發現的已過期的key if (val.expires < new Date().getTime()) { list.splice(index, 1); localStorage.removeItem(key); expireCount++; } } //若刪除的key不超過5個則跳出迴圈 if (expireCount <= 5 || list.length == 0) { break; } checkCount++; } } //每隔一秒執行一次定時刪除 window.setInterval(self.check, 1000); return self; }(lsc || {})); ``` ### 完整原始碼及使用示例 完整原始碼及使用示例已上傳到[我的GitHub](https://github.com/heihaozi/LocalStorageCache)(https://github.com/heihaozi/LocalStorageCache)上,感謝各位小夥伴的Star和Fork。 ### 總結 一種策略可能會有自己的缺點,為了規避相應的缺點,我們可以合理運用多種策略,揚長避短就得到接近完美的解決方案。

微信公眾號:萬貓學社

微信掃描二維碼

獲得更多Java技術乾貨