zoukankan      html  css  js  c++  java
  • javascript数据缓存策略之本地存储

    昨天看了司徒正美的博客http://www.cnblogs.com/rubylouvre/archive/2012/09/14/2684061.html讲到一个很完美的文件加载方案,思考很久,收益颇深。他考虑的很全面,但是美中不足的是并没有考虑ie6、7的情况,ie6、7下单个文件最大值能存64K,很多大文件是无法加载的,尤其是新版的jquery。

    如果把这个思路再扩展一下,放到数据缓存里面来,将是一个很完美的解决方案。

    我们先完成一个本地存储的DB类。

    db = function() {
        var store = window.localStorage, doc = document.documentElement;
        if (!store) {
            doc.style.behavior = 'url(#default#userData)';
        }
        return {
            /**
             * 保存数据
             */
            set : function(key, val, context) {
                if (store) {
                    return store.setItem(key, val, context);
                } else {
                    doc.setAttribute(key, value);
                    return doc.save(context || 'default');
                }
            },
            /**
             * 读取数据
             */
            get : function(key, context) {
                if (store) {
                    return store.getItem(key, context);
                } else {
                    doc.load(context || 'default');
                    return doc.getAttribute(key) || '';
                }
            },
            /**
             * 删除数据
             * @param {Object}
             * @param {Object}
             */
            rm : function(key, context) {
                if (store) {
                    return store.removeItem(key, context);
                } else {
                    context = context || 'default';
                    doc.load(context);
                    doc.removeAttribute(key);
                    return doc.save(context);
                }
            },
            /**
             * 清空数据
             */
            clear : function() {
                if (store) {
                    return store.clear();
                } else {
                    doc.expires = -1;
                }
            }
        };
    }();

    然后我们再写一个简单的ajax函数。

    if ( typeof window.XMLHttpRequest === "undefined") {
        window.XMLHttpRequest = function() {
            return new window.ActiveXObject(navigator.userAgent.indexOf("MSIE 5") >= 0 ? "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP");
        };
    }
    ajax = function(uri, options) {
        var httpRequest, httpSuccess, timeout, isTimeout = false, isComplete = false, noop = function() {
        };
    
        options = {
            method : options.method || "GET",
            data : options.data || null,
            arguments : options.arguments || null,
    
            onSuccess : options.onSuccess || noop,
            onError : options.onError || noop,
            onComplete : options.onComplete || noop,
            onTimeout : options.onTimeout || noop,
            isAsync : options.isAsync || true,
            timeout : options.timeout ? options.timeout : 30000,
            contentType : options.contentType ? options.contentType : "utf-8",
            type : options.type || "xml"
        };
        uri = uri || "";
        timeout = options.timeout;
    
        httpRequest = new window.XMLHttpRequest();
        httpRequest.open(options.method, uri, options.isAsync);
        //设置编码集
        httpRequest.setRequestHeader("Content-Type", options.contentType);
    
        /**
         * @ignore
         */
        httpSuccess = function(r) {
            try {
                return (!r.status && location.protocol == "file:") || (r.status >= 200 && r.status < 300) || (r.status == 304) || (navigator.userAgent.indexOf("Safari") > -1 && typeof r.status == "undefined");
            } catch(e) {
            }
            return false;
        }
        /**
         * @ignore
         */
        httpRequest.onreadystatechange = function() {
            if (httpRequest.readyState == 4) {
                if (!isTimeout) {
                    var o = {};
                    o.responseText = httpRequest.responseText;
                    o.responseXML = httpRequest.responseXML;
                    o.data = options.data;
                    o.status = httpRequest.status;
                    o.uri = uri;
                    o.arguments = options.arguments;
    
                    if (httpSuccess(httpRequest)) {
                        if (options.type === "script") {
                            eval.call(window, data);
                        }
                        options.onSuccess(o);
    
                    } else {
                        options.onError(o);
                    }
                    options.onComplete(o);
                }
                isComplete = true;
                //删除对象,防止内存溢出
                httpRequest = null;
            }
        };
    
        httpRequest.send(options.data);
    
        window.setTimeout(function() {
            var o;
            if (!isComplete) {
                isTimeout = true;
                o = {};
                o.uri = uri;
                o.arguments = options.arguments;
                options.onTimeout(o);
                options.onComplete(o);
            }
        }, timeout);
    
        return httpRequest;
    };

    好了,最后说一下解决方案,源码如下:

    var cacheData = {};
    cache = function(url, func, cacheTime) {
        //先读内存
        if(cacheData[url]){
            func.call(this, cacheData[url]);
            return;
        }else{
            var me = this,
            chData = db.get(url), 
            chTime = db.get(url + "__time"), 
            now = new Date().getTime(), 
            cacheTime = cacheTime || 60, 
            ct = now - 60000 * cacheTime, //默认缓存时间为1个小时
            success = function(data) {
                var res = data.responseText;
                cacheData[url] = res;
                db.set(url, res);
                db.set(url + "__time", now);
                func.call(me, res);
            };
            //存在数据的情况
            if (chData && chTime) {
                //未过期的情况
                if (ct < chTime) {
                    func.call(this, chData);
                } else {//过期的情况
                    ajax(url, {'onSuccess' : success});
                }
            } else {
                ajax(url, {'onSuccess' : success});
            }
        }
        
    }

    over。

  • 相关阅读:
    MySQL修改root密码的多种方法
    (转)云存储:阿里云OSS 、又拍云和 七牛 的比较
    微博feed系统的推(push)模式和拉(pull)模式和时间分区拉模式架构探讨
    Feed系统架构资料收集
    百万用户时尚分享网站feed系统扩展实践
    (转)浅谈MD5加密算法中的加盐值(SALT)
    json转换成list map集合
    android在假设绘制自己定义的bitmap,然后返回给ImageView
    APPCAN学习笔记003---原生开发与HTML5技术
    【问题解决】syntax error: unexpected end of file或-bash: ./full_build.sh: /bin/bash^M: bad interpreter: No
  • 原文地址:https://www.cnblogs.com/xpbb/p/2685916.html
Copyright © 2011-2022 走看看