H 5のlocalStorageローカルキャッシュオブジェクトをカプセル化し、キャッシュ有効期間、キャッシュ本数制限を実現

9031 ワード

宣言方法:
/*
 *    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