封装H5的localStorage本地缓存对象,实现缓存有效期、缓存条数限制

声明方式:

/*
 *    indexKey 缓存名
 *    cacheSize 缓存个数
 */
  var localCache = new LRUCache(indexKey, cacheSize);

调用方式:

  • 添加:localCache.put(key, value, expires);
  • 获取: localCache.get(key);
  • 清除:localCache.clear();
  • 删除:localCache.remove(key);
  • 删除最后一个:localCache.removeLast();

LRUCache .js源代码

//加载插件:https://cdn.bootcss.com/crypto-js/3.1.9/crypto-js.js
var CryptoJS = require( 'crypto' );
/**
 * **********************************************************************
 * 说明:    缓存对象LRU策略
 * 声明方式:
 *    indexKey 缓存名
 *    cacheSize 缓存个数
 * 
 *   var localCache = new LRUCache(indexKey, cacheSize);
 * 调用方式:
 *   添加:localCache.put(key, value, expires);
 *   获取: localCache.get(key);
 *   清除:localCache.clear();
 *   删除:localCache.remove(key);
 *   删除最后一个:localCache.removeLast();
 * **********************************************************************
 */
/**
 * 缓存对象
 * @param indexKey 缓存名
 * @param cacheSize 缓存个
 * @constructor
 */
function LRUCache ( indexKey, cacheSize ) {
  // 秒 分 时 一天
  var expiresTime      = 60 * 24 * 365;
  var currentSize      = 0; // 当前大小
  var cacheSize        = cacheSize ; //缓存大小
  var keyArray         = [];//缓存容器
  var localStorage     = window.localStorage || {
      getItem:function() {
        return null;
      },
      setItem:function() {
      }
    }; // 缓存全局localStorage对象局部变量
  indexKey             = sha1( indexKey );
  /**
   * 加载localStorage中的数据,并且判断是否有忆失效的
   */
  keyArray = JSON.parse( getLocalStorage( indexKey ) ) || [];
  currentSize = keyArray.length;
  for ( var i = 0; i < keyArray.length; i++ ) {
    var time    = +keyArray[ i ].time;
    var nowTime = +new Date();
    if ( nowTime > time ) {
      removeLocalStorage( keyArray[ i ].key );
      keyArray.splice( i, 1 );
    }
    saveKeyIndexLocalStorage();
  }
  /**
   * hash加密->sha1算法
   * @param str
   */
  function sha1 ( str ) {
    return CryptoJS.SHA1( str ).toString();
  }

  /**
   * 获取字符串长度(汉字算两个字符,字母数字算一个)
   * @author @DYL
   * @DATE 2017-11-21
   */
  function getByteLen ( val ) {
    var len = 0;
    for ( var i = 0; i < val.length; i++ ) {
      var a = val.charAt( i );
      if ( a.match( /[^\x00-\xff]/ig ) != null ) {
        len += 2;
      }
      else {
        len += 1;
      }
    }
    return len;
  }

  function saveKeyIndexLocalStorage ( obj ) {
    if ( obj ) {
      keyArray.unshift( obj );
    }
    localStorage.setItem( indexKey, JSON.stringify( keyArray ) );
  }

  /**
   * 把数据保存到localStorage中
   * @expire 单独是分钟
   * @param obj Object类型
   */
  function saveLocalStorage ( key, value ) {
    localStorage.setItem( key, value );
  }

  function removeLocalStorage ( key ) {
    removeLastLocalStorage( key )
  }

  function removeLastLocalStorage ( key ) {
    currentSize--;
    localStorage.removeItem( key );
  }

  function getLocalStorage ( key ) {
    return localStorage.getItem( key );
  }

  /**
   * 添加缓存
   * @param key
   * @param value
   */
  function put ( key, value, expires ) {
    // 判断是不是已经存在了缓存对象
    var item = get( key );
    value = JSON.stringify( value ); //将对象转换成字符JSON
    key   = sha1( key );
    if ( item ) {
      moveToHead( key );
    } else {
      //缓存容器是否已经超过大小.
      if ( currentSize >= cacheSize ) {
        removeLast();
      } else {
        currentSize++;
        expires = expires || expiresTime;
        expires = +new Date() + expires * 60 * 1000; // 默认一天失效
        saveKeyIndexLocalStorage( { key:key, time:expires, size:getByteLen( value ) } );
      }
    }
    saveLocalStorage( key, value );
  }

  /**
   * 获取缓存中对象
   * @param key
   * @return
   */
  function get ( key ) {
    key = sha1( key );
    moveToHead( key );
    return JSON.parse( getLocalStorage( key ) );
  }

  /**
   * 将缓存删除
   * @param key
   * @return
   */
  function remove ( key ) {
    key = sha1( key );
    for ( var i = 0, len = keyArray.length; i < len; i++ ) {
      if ( key == keyArray[ i ].key ) {
        currentSize--;
        keyArray.splice( i, 1 );
        removeLocalStorage( key );
        saveKeyIndexLocalStorage();
        break;
      }
    }
  }

  /**
   * 清仓缓存cachaName中的数据
   */
  function clear () {
    keyArray    = [];
    currentSize = 0;
    localStorage.clear();
  }

  /**
   * 删除链表尾部节点
   *  表示 删除最少使用的缓存对象
   */
  function removeLast () {
    var key = keyArray.pop();
    removeLastLocalStorage( key );
  }

  /**
   * 移动到链表头,表示这个节点是最新使用过的
   * @param node
   */
  function moveToHead ( key ) {
    var item = {};
    for ( var i = 0; i < keyArray.length; i++ ) {
      item = keyArray[ i ];
      if ( key == item.key && i != 0 ) {
        //如果不是第一个元素,就把它从数字中删除,再把它添加到数组顶端
        item = keyArray.splice( i, 1 )[ 0 ];
        saveKeyIndexLocalStorage( item );
        break;
      }
    }
  }

  this.get        = get;
  this.put        = put;
  this.remove     = remove;
  this.clear      = clear;
  this.removeLast = removeLast;
  this.moveToHead = moveToHead;
}
window.LRUCache = LRUCache;

参考文档:

缓存淘汰算法–LRU算法
http://flychao88.iteye.com/blog/1977653

猜你喜欢

转载自blog.csdn.net/itpinpai/article/details/79030070