• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >jquery > 对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解

对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解

作者: 字体:[增加 减小] 来源:互联网

通过本文主要向大家介绍了jquery,ajax,二次封装,ajax缓存,AjaxCache等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

虽然jquery的较新的api已经很好用了, 但是在实际工作还是有做二次封装的必要,好处有:1,二次封装后的API更加简洁,更符合个人的使用习惯;2,可以对ajax操作做一些统一处理,比如追加随机数或其它参数。同时在工作中,我们还会发现,有一些ajax请求的数据,对实时性要求不高,即使我们把第一次请求到的这些数据缓存起来,然后当相同请求再次发起时直接拿之前缓存的数据返回也不会对相关功能有影响,通过这种手工的缓存控制,减少了ajax请求,多多少少也能帮助我们提高网页的性能。本文介绍我自己关于这两方面问题的做法,欢迎交流和指正。

点击 代码下载 (注:因为用到了ajax,所以不能在file协议下运行,必须运行在http下)

1. 封装jquery的ajax

其实这个部分的相关内容在之前的一篇博客引入过,只不过那里面只是引用,没有详细说明,另外ajax缓存代理组件的实现也是基于这个二次封装之后的ajax组件的,所以有必要在这里对它详细说明一下,虽然实现并不复杂(详见注释说明):

define(function (require, exports, module) {

  var $ = require('jquery');

  //根据关键的几个参数统一创建ajax对象
  function create(_url, _method, _data, _async, _dataType) {
    //添加随机数
    if (_url.indexOf('?') > -1) {
      _url = _url + '&rnd=' + Math.random();
    } else {
      _url = _url + '?rnd=' + Math.random();
    }

    //为请求添加ajax标识,方便后台区分ajax和非ajax请求
    _url += '&_ajax=1';

    //返回jquery创建的ajax对象,以便外部拿到这个对象以后可以通过
    //.done .fail .always来添加回调
    //这么做是为了保留jquery ajax中好用的部分
    return $.ajax({
      url: _url,
      dataType: _dataType,
      async: _async,
      method: _method,
      data: _data
    });
  }

  //ajax就是本组件全局唯一的实例,它的实例方法通过后面的循环代码添加
  //methods对象配置ajax各个实例方法的参数:
  //name: 方法名称
  //method: http请求方法,get or post
  //async: 发送请求时是否异步
  //dataType: 返回的数据类型,html or json
  var ajax = {},
    methods = [
      {
        name: 'html',
        method: 'get',
        async: true,
        dataType: 'html'
      },
      {
        name: 'get',
        method: 'get',
        async: true,
        dataType: 'json'
      },
      {
        name: 'post',
        method: 'post',
        async: true,
        dataType: 'json'
      },
      {
        name: 'syncGet',
        method: 'get',
        async: false,
        dataType: 'json'
      },
      {
        name: 'syncPost',
        method: 'post',
        async: false,
        dataType: 'json'
      }
    ];

  //由于二次封装需要对外提供的每个实例方法创建ajax的逻辑是相同的
  //所以通过这种方式统一定义各个实例方法
  //关键代码为下面代码中的那个立即调用的函数
  //它返回了一个新的闭包函数作为实例方法
  for (var i = 0, l = methods.length; i < l; i++) {
    ajax[methods[i].name] = (function (i) {
      return function () {
        /**
         * 每个实例方法接收三个参数
         * 第一个表示要请求的地址
         * 第二个表示要提交到后台的数据,是一个object对象,如{param1: 'value1'}
         * 第三个表示后台返回的数据类型,最最常用的就是html or json,绝大部分情况下这个参数不用传,会使用methods里面定义的dataType
         */
        var _url = arguments[0],
          _data = arguments[1],
          _dataType = arguments[2] || methods[i].dataType;

        return create(_url, methods[i].method, _data, methods[i].async, _dataType);
      }
    })(i);
  }

  return ajax;
});

1)统一提供随机数参数和ajax请求标识;
2)对jquery的api进行了包装,对外提供的方法更加清晰明了。

使用方式:

define(function (require, exports, module) {

  var Ajax = require('mod/ajax');

  //以GET方式请求html内容
  Ajax.html('html/demo', {
    param1: 'value1',
    param2: 'value2'
  }).done(function(response){
    //请求成功的回调
  }).fail(function(){
    //请求失败的回调
  }).always(function(){
    //请求完成的回调
  });

  //以GET方式请求json数据
  Ajax.get('api/demo', {
    param1: 'value1',
    param2: 'value2'
  }).done(function(response){
    //请求成功的回调
  }).fail(function(){
    //请求失败的回调
  }).always(function(){
    //请求完成的回调
  });

  //以POST方式请求json数据
  Ajax.post('api/demo', {
    param1: 'value1',
    param2: 'value2'
  }).done(function(response){
    //请求成功的回调
  }).fail(function(){
    //请求失败的回调
  }).always(function(){
    //请求完成的回调
  });

  //以GET方式发送同步请求,获取json数据
  Ajax.syncGet('api/demo', {
    param1: 'value1',
    param2: 'value2'
  }).done(function(response){
    //请求成功的回调
  }).fail(function(){
    //请求失败的回调
  }).always(function(){
    //请求完成的回调
  });

  //以POST方式发送同步请求,获取json数据
  Ajax.syncPost('api/demo', {
    param1: 'value1',
    param2: 'value2'
  }).done(function(response){
    //请求成功的回调
  }).fail(function(){
    //请求失败的回调
  }).always(function(){
    //请求完成的回调
  });

});

由于这个组件的每个实例方法返回的对象就是$.ajax创建的对象,所以我们完全可以照常使用.done .fail .always来添加回调,就跟直接用$.ajax没有任何区别。为什么API要设计成html, get, post, syncGet, syncPost这几个方法,而且连dataType基本都是固定的?

那是因为在项目中,我们完全可以约定在异步请求的时候只能用html或json这两种dataType,其它dataType不允许,现在的web项目这两种方式已经完全够用了,至少我没有碰到过非得使用别的dataType不可的情况;而且在实际工作当中html, get, post, syncGet, syncPost这几个方法几乎能够涵盖我们需要的所有异步请求的场景,每当我们要用ajax的时候,无非考虑的就是get还是post,同步还是异步,请求的是html还是json这三个问题,通过它们就能把每个问题都解决了。当然jsonp,rest API这两种情况就另说了,这个组件不是为它们服务的,这也是它的局限性,它还是倾向于在传统的web项目中使用。

2. ajax缓存代理

要实现一个简单的ajax缓存代理组件,首先要清楚这个缓存代理的作用,在本文开篇说到过缓存代理的应用场景:当使用缓存代理第一个发起某个请求时,在请求成功后将数据缓存下来,然后当再次发起相同请求时直接返回之前缓存的数据,缓存代理的作用是控制何时发送请求去后台加载数据,何时不发送请求直接从缓存中读取之前加载的数据。为了实现一个简单的缓存代理,有三个问题要解决:

1)代理对象必须与被代理的对象有相同的API
拿前面的Ajax组件来说,它提供有html, get , post, syncGet, syncPost方法,那么它的代理对象也必须同时具有这些方法,而且调用方式,传入参数都必须完全一致,只有这样,当我们在使用代理对象的时候,就跟在使用原组件对象没有区别。而且在缓存代理内部,在某些条件下是需要调用原组件对象发送ajax请求的,如果接口不同,调用方式不同,参数不同,如何能保证内部能够正确调用原组件对象呢?这个条件还有一个好处,就是当我们下次不想使用代理对象的时候,能够以最小的代价将代理对象替换为原组件对象。
这一点其实是设计模式中代理模式的基本要求。

2)缓存数据存储时的缓存索引问题
也就是说我们以什么样的索引才能保证同一个请求的数据在缓存之后,下次查找时还能根据请求信息查找到呢?ajax缓存有别于其它缓存的地方在于它请求的地址可能包含可变的参数值,同一个地址如果后面的参数不同,那么对应的请求结果也就不一定相同,所以简单起见,可以考虑把请求地址跟请求参数统一作为缓存索引,这样就能对缓存进行简单管理。同时考虑到其它可变性,还应有其它的一些要求,详见后面组件实现中的注释说明。

3)缓存有效时间
虽然要实现的缓存代理很简单,但是这个问题一定是要考虑的,每个缓存代理实例,能够缓存数据的有效时间不一定相同,有的可能只缓存几分钟,有的可能缓存几十分钟,当缓存时间失效时,缓存代理就得删除原来的缓存,然后重新去加载数据才行。

综合这些问题,基于第一部分的Ajax组件,最终实现的缓存代理组件AjaxCache的代码如下(有注释详解):

define(function (require, exports, module) {

  var $ = require('jquery');
  var Ajax = require('mod/ajax');

  //缓存列表
  var cache = {};

  /**
   * 生成缓存索引:
   * 由于索引是根据url和data生成的(data是一个对象,存放Ajax要提交到后台的数据)
   * 所以要想同一个url,同样的data能够有效地使用缓存,
   * 切勿在url和data中包



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 基于jQuery对象和DOM对象和字符串之间的转化实例
  • jquery+css实现简单的图片轮播效果
  • 使用jQuery实现鼠标点击左右按钮滑动切换
  • jQuery实现上传图片前预览效果功能
  • jQuery初级教程之网站品牌列表效果
  • 基于jquery实现多选下拉列表
  • jQuery接受后台传递的List的实例详解
  • 详解jquery选择器的原理
  • jQuery上传插件webupload使用方法
  • 关于jquery form表单序列化的注意事项详解

相关文章

  • jQuery实现防止提交按钮被双击的方法
  • jquery判断RadioButtonList和RadioButton中是否有选中项示例
  • Jquery创建层显示标题和内容且随鼠标移动而移动
  • JQuery中对服务器控件 DropdownList, RadioButtonList, CheckboxList的操作总结
  • jQuery序列化后的表单值转换成Json
  • jquery trigger伪造a标签的click事件取代window.open方法
  • jquery ztree实现模糊搜索功能
  • jquery遍历table的tr获取td的值实现方法
  • jQuery grep()方法详解及实例代码
  • jQuery实现的倒计时效果实例小结

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 基于jquery封装的一个js分页
    • JQuery 动态生成Table表格实例代码
    • Jquery获取和修改img的src值的方法
    • jquery之超简单的div显示和隐藏特效demo(分享)
    • 详解获取jq ul第一个li定位的四种解决方案
    • EasyUi tabs的高度与宽度根据IE窗口的变化自适应代码
    • jQuery获取父级元素、子级元素、兄弟元素的方法
    • jQuery插件zTree实现的基本树与节点获取操作示例
    • jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
    • jQuery获取父元素及父节点的方法小结

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有