2

ExpiredStorage-给localstroage增加超时功能 源码解读

 2 years ago
source link: https://segmentfault.com/a/1190000040785544
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

ExpiredStorage-给localstroage增加超时功能 源码解读

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左右的下载量,佩服!!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK