乐道

乐在其中,道不出口

 

jquery ajax使用代理缓存避免重复请求

在jquery的1.5版本中加了一个Deferred对象,jq的代码也做了大规模重写。如果想要了解该对象,推荐阅读:jQuery Deferred对象详细源码分析(-)

jq的ajax方法也用Deferred对象加入了新特性,现在我们来使用ajax新特性来实现xhr的代理缓存,主要目的:避免重复请求。

注意:代理缓存主要用来cache从server拉取的数据,对于client发数据到server处理的情况不要使用

对同一url二次请求分为两种情况

  • 情况一:第一次请求还未完成,发出了第二次请求;
  • 情况二:第一次请求已完成,再发出了第二次请求。

所以我们需要用到两个对象,一个__xhrCache__保存jqXhr,一个__dataCache__保存请求的结果

var jqXhrCache = {
            __xhrCache__: {}, 
            __dataCache__: {},
            request: function(op, doneCallback, failCallback) {
                var url = typeof op === 'string' ? op : op.url,
                    enUrl = encodeURIComponent(url), 
                    xca = this.__xhrCache__,
                    dca = this.__dataCache__;
                if(!xca[enUrl]) {
                    xca[enUrl] = $.ajax(op).done(function(data) {
                        dca[enUrl] = data;
                    });
                }
                if(dca[enUrl] === undefined) {
            /*情况一:将第二次请求的回调事件追加给缓存的jqXhr对象*/ xca[enUrl].done(doneCallback).fail(failCallback); }
else {
            /*情况二:代入缓存结果执行第二次请求的回调事件*/ doneCallback.call(
null, dca[enUrl], xca[enUrl]); } return xca[enUrl]; } };

上面版本的不足之处是__xhrCache__和__dataCache__可能会被意外修改,虽然从命名上看起来像私有成员,但还是有被外界篡改的风险,那么下面使用闭包使它们真正私有化

var jqXhrCache = (function() {
            var __xhrCache__ = {}, __dataCache__ = {};
            return {
                request: function(op, doneCallback, failCallback) {
                    var url = typeof op === 'string' ? op : op.url,
                        enUrl = encodeURIComponent(url), 
                        xca = __xhrCache__,
                        dca = __dataCache__;
                    if(!xca[enUrl]) {
                        xca[enUrl] = $.ajax(op).done(function(data) {
                            dca[enUrl] = data;
                        });
                    }
                    if(dca[enUrl] === undefined) {
                        xca[enUrl].done(doneCallback).fail(failCallback);
                    } else {
                        doneCallback.call(null, dca[enUrl], xca[enUrl]);
                    }
                    return xca[enUrl];
                }
            };
        })();

 

到这里已经可以避免同一url的二次请求了,但这里cache对象在浏览器刷新或重新打开后又会被重置;如果需要长久保存请求的结果(如县市资料等不经常变动的数据),可以考虑使用html5中的localStorage。

使用方法:jqXhrCache.request('/testDefer.html', function(data) { console.log(data) }, function() { console.log('request fail') });

posted on 2012-10-29 21:52  乐道  阅读(3184)  评论(3编辑  收藏  举报

导航