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

来源:互联网 发布:华讯网络怎么样 编辑:程序博客网 时间:2024/04/27 16:58

在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') });

原创粉丝点击