ExpiredStorage-給localstroage增加超時功能 原始碼解讀

阿古達木發表於2021-10-09

https://www.npmjs.com/package...
這個庫擴充了localStroage。在設定item的時候,會另外再設定一個key用來儲存過期時間。當在取資料的時候判斷是否過期並且remove元素。


用法

expiredStorage = new ExpiredStorage();

// 60秒後過期
expiredStorage.setItem("test", "foobar", 60);
// 永不過期
expiredStorage.setItem("no_expire", "this will live forever");
// 獲取資料,如果過期會返回null
var item = expiredStorage.getItem("test");
// 獲取剩餘時間
var timeLeft = expiredStorage.getTimeLeft("test");
// 檢測key是否過期
var isExpired = expiredStorage.isExpired("test");
 
// 獲取所有的key(如果includeExpired是true, 連過期沒來的刪除的key也一併返回)
var keys = expiredStorage.keys(includeExpired);
 
// 返回這個key的詳情
var data = expiredStorage.peek("test");

原始碼解讀
建構函式,這塊就是一些邊界判斷,沒什麼

function ExpiredStorage(storage) {
        ...
        this._storage = storage;
    }

重點是setItemgetItem

ExpiredStorage.prototype = {
    // 基礎stroage類,在建構函式中賦值
    _storage: null,
    // 時間戳key的字首
    _expiration_key_prefix: "__expired_storage_ts__",
    // 獲取當前時間 單位秒
    getTimestamp: function() {
        return Math.floor(((new Date).getTime()) / 1000);
    },
    setItem: function(key, value, expiration) {
        // set item
        var ret = this._storage.setItem(key, value);
        // 儲存這個key對應的過期時間 (僅僅在expiration有值的時候)
        if (expiration) {
            this.updateExpiration(key, expiration);
        }
        return ret;
    },
    // 更新key的過期時間,新的key位時間戳字首加舊的key
    updateExpiration: function(key, expiration) {
        return this._storage.setItem(this._expiration_key_prefix + key, this.getTimestamp() + expiration);
    },

    getItem: function(key) {
        // 判斷是否過期,過期了就刪除這一項,返回null
        if (this.isExpired(key)) {
            this.removeItem(key);
            return null;
        }
        // 沒過期就正常返回
        return this._storage.getItem(key);
    },

    // 判斷是否過期
    isExpired: function(key) {
        var timeLeft = this.getTimeLeft(key);
        return timeLeft !== null && timeLeft <= 0;
    },

    // 獲取剩餘時間
    getTimeLeft: function(key) {
        // 通過時間戳key拿到過期時間
        var expireTime = parseInt(this._storage.getItem(this._expiration_key_prefix + key));

        // 取到值就返回剩餘時間
        if (expireTime && !isNaN(expireTime)) {

            return expireTime - this.getTimestamp();
        }

        // 沒取到值就返回null
        return null;
    },
    // 同時刪除key和時間戳key
    removeItem: function(key) {
        var ret = this._storage.removeItem(key);
        this._storage.removeItem(this._expiration_key_prefix + key);
        return ret;
    },
}

非常簡單就實現了一個比較麻煩的需求,這個倉庫已經四年沒更新,還保持著每週1k左右的下載量,佩服!!

相關文章