`
Liner
  • 浏览: 141597 次
  • 性别: Icon_minigender_1
  • 来自: 西南边陲
社区版块
存档分类
最新评论

具有xhr对象管理功能的Ajax简易封装(Majax)

阅读更多
内部由一个数组缓存工作中的xhr对象,类似于“池”,当一个请求发生时,由池中首个空闲的xhr对象执行相关操作,当请求处理完毕后,对象被回收。

这在网络速度无法保证、服务器端响应较慢,而Ajax采用异步方式时很有用。外部可以把一个Majax实例当作具有自动缓冲机制并持久有效的异步通讯对象看待。

使用接口简单并且灵活,回调函数接口也十分友好。详细内容可参看源码中的注释,希望大家喜欢。

用法:
<script language="javascript" src="majax.js"></script>
<script language="javascript">
function callback(req, id) {
    // 直接使用
    document.getElementById(id).innerHTML = req.responseText;
}
var _mObj = new Majax();
</script>
<div id="someid"></div>
<div onClick="_mObj.get('/yourscript.php?name=xxx', callback, 'someid')">GET方式</div>
<div onClick="_mObj.post('/yourscript.php', 'name=xxx', callback, 'someid')">POST方式</div>


提示:回调函数中的第二个参数可以传递任意类型的数据,所以可以在异步设计的时候用于协调一些状态。使用中如果发现Bug,欢迎在此留言或Email:tubz@21cn.com

接口示例(假如已 var _mObj = new Majax();):
//-- 普通接口 -----------------------------------------------------------------

// GET方式请求。
// (URL, 回调函数, 传递给回调函数的附加数据, 是否异步)
_mObj.get(url, callback, fd, asyn)

// POST方式请求,Post-data仅为文本。
// (URL, POST数据, 回调函数, 传递给回调函数的附加数据, 是否异步)
_mObj.post(url, data, callback, fd, asyn)

//-- 低阶接口 -----------------------------------------------------------------

// 复位/设置请求。
// (URL, [GET|POST]方法, 是否异步)
_mObj.reset(url, method, asyn)

// 设置请求头信息。
_mObj.header(name, value)

// 发送请求(若reset时为GET,data为null)。
// (发送数据, 回调函数, 传递给回调函数的附加数据)
_mObj.send(data, callback, fd)

// 设置出错处理函数
// func(req, callback)
_mObj.e_handler(func)


压缩包内文件说明:
  majax.js 用jsmin压缩过的纯代码,实际引用文件;
  majax_.js 书写时的源代码,含注释;
  test.html/servdt.php 测试用文件。
  • majax_v0.1.rar (3.5 KB)
  • 描述: 带请求对象池管理功能的Ajax封装,接口兼顾灵活与简便。
  • 下载次数: 46
  • majax_v0.2.rar (4.2 KB)
  • 描述: 增加了出错处理接口,修复出错时xhr对象无法回收的问题。
  • 下载次数: 107
分享到:
评论
7 楼 Liner 2007-07-28  
引用

所谓忠言逆耳,既然你不想听,那我也打住。

首先谢谢你的回复,讲解得很详细。(真心感谢,我很菜,所以希望能得到明白人的指点,最好是有代码说明)
我那个到此打住的意思希望不要被顶上去,影响别的好贴被下沉。
引用

6.关于泄漏,把我的揶揄之词当成你的理由,真令人哭笑不得。

因为在论坛上我不揶揄别人(除非是老朋友),所以没看出来。
引用

>>1、请勿在回调函数和错误处理函数中抛出异常。
这点约束是非常不明智的。

是的,如果要通用就该改一下。
我本来的想法是希望用户在回调函数或错误处理中就解决掉内层抛出的异常,不再往外发(设计上的强制,但未必可行)。

其实还有一个不足,就是异步时返回的xhr对象不能被滥用。这个引用对象在对应请求的回调函数执行完之后会被回收,所以再在其上操作其实是针对另一个请求的——除非那就是想要的,否则就错了。
我本来是不想提供返回,但为灵活性还是返回了。

………………………………………………………………………………………………………………………………………

如果需要取消上面“勿在回调函数和错误处理函数中抛出异常”的限制,可以用下面的代码替换压缩包中对应的函数。
Majax._callback = function(callback, data, its, obj)
{
    var _req = its[0];

    if(_req.readyState == 4) {
        try {
            if(_req.status != 200) {
                if(obj._eh) obj._eh(its[0], callback);
            }else{
                callback(_req, data);
            }
        } finally {
            its[1] = false;
        }
    }
}

不知道该如何捕获xhr异步调用回调函数时从回调函数中抛出的异常?我觉得不应该在这里捕获,应该放行异常继续向上,或许由浏览器显示那些“难看”的代码,呵呵。
6 楼 jindw 2007-07-28  
引用

>> 补充:

1、请勿在回调函数和错误处理函数中抛出异常。


这点约束是非常不明智的。
5 楼 hax 2007-07-28  
Liner 写道
新创建一个xhr对象的开销有多大我不清楚,但是在实际应用中必须顾及浏览器的兼容性,所以创建一个xhr对象其实是需要一些代码的,比如:

但是,如果创建的对象被保留下来,在可以安全使用的前提下,返回一个现成的对象肯定要比新创建一个兼容对象快不少。对于池的复杂性,封装就是为了掩盖复杂性的,用户只需要面对接口。(白:其实代码并不复杂)

在一个页面存在大量Ajax请求的应用里,从消耗累加的角度看,用这个封装明显比每次都创建一个新的xhr要高效和节约。并且由于重复使用xhr对象,还可缓解hax所说的IE6存在的内存泄漏问题。

比较简单的东西……到此打住。


1. 既然多大开销你不清楚,那就没有充分理由用池。因为你的池可能开销更大。
2. 创建一个xhr的兼容代码不需要那么复杂。对于支持native xhr的(ff,opera,safari,ie7),根本不需要任何额外代码;对于IE6及以前的,只需要初始的时候创建一个XMLHttpRequest函数,且该函数根本不用每次都循环try catch(这是一个基本的js编程,留给大家当作业吧)。
3. 不管你掩盖的如何,如果你掩盖的复杂性本身就是没有必要的,那就应该以剃刀原则去除之。
4. 前面还说你不知道开销多少,后面又说高效节约,不知道才过了两段文字,就哪里明显了?
5. 请你好好再读读我前面的帖子,看看我为什么说js对象池没有必要,以及就算要实现池你也没实现到位。
6. 关于泄漏,把我的揶揄之词当成你的理由,真令人哭笑不得。

所谓忠言逆耳,既然你不想听,那我也打住。
4 楼 Liner 2007-07-28  
新创建一个xhr对象的开销有多大我不清楚,但是在实际应用中必须顾及浏览器的兼容性,所以创建一个xhr对象其实是需要一些代码的,比如:
function new_object()
{
    var A;
    var _msxmlhttp = new Array(
        'Msxml2.XMLHTTP.6.0',
        //'Msxml2.XMLHTTP.5.0',
        //'Msxml2.XMLHTTP.4.0',
        'Msxml2.XMLHTTP.3.0',
        'Msxml2.XMLHTTP',
        'Microsoft.XMLHTTP');
    for(var i = 0; i < _msxmlhttp.length; i++) {
        try {
            if(A = new ActiveXObject(_msxmlhttp[i])) break;
        } catch (e) {
            A = null;
        }
    }
    if(!A && typeof XMLHttpRequest != "undefined")
        A = new XMLHttpRequest();
    if(!A)
        alert("Could not create connection object.");

    return A;
}


但是,如果创建的对象被保留下来,在可以安全使用的前提下,返回一个现成的对象肯定要比新创建一个兼容对象快不少。对于池的复杂性,封装就是为了掩盖复杂性的,用户只需要面对接口。(白:其实代码并不复杂)

在一个页面存在大量Ajax请求的应用里,从消耗累加的角度看,用这个封装明显比每次都创建一个新的xhr要高效和节约。并且由于重复使用xhr对象,还可缓解hax所说的IE6存在的内存泄漏问题。

比较简单的东西……到此打住。
3 楼 hax 2007-07-23  
池增加了代码复杂度,反而可能降低效率。我估计,native的new XMLHttpRequest肯定应比你的池要高效。只有IE6,因为是创建一个AcitveX对象,可能较为低效。但是这种效率提高到底有多少?非常值得怀疑。

事实上,对象池技术在多数场合并无必要,例如在java中,只有重量级资源对象,或者反复创建相同的对象并可能影响性能,才会使用对象池。

而在js里面:
1. js对象只是XHR的wrapper,纯粹new一个js对象的开销不会比你复杂的池要大,只会小。
2. XHR自己可能存在优化。实际上,UA自己或者更底层的网络协议层,对于http请求都是有队列的。所以不用你画蛇添足。
3. 就算要用池,浏览器同源请求在同一时刻只能有2个,不同源的也有一定上限(通常10个以下),所以你真的要做池的话,其实应该控制上限。

总之,XHR的池是毫无意义的——除非你有数据证明它确实提高了效率。

BTW,使用你这个代码的“好处”是,虽然你的这个代码在IE6上会有内存泄漏,但同样是泄漏,因为你重复利用了XHR对象,所以估计你的泄漏量会小。
2 楼 Liner 2007-07-23  
确实,我不清楚xhr对象在每个浏览器实现中的开销,但是如果池的实现也很高效的话,用池就是值得的。
源码是LGPL的(很简单的东西,其实基本上都谈不上什么版权之类的),如果你看源码,会发现这点。
当然欢迎你进一步优化它并共享一哈,呵呵。

>>反复利用同一个xhr在某些平台上可能有问题。
请教会在什么平台什么情况下有问题?
当一个对象被重用的时候,会被open重新初始化的,并且只有当回调函数执行完之后,对象才会被回收。
1 楼 hax 2007-07-21  
1. 反复利用同一个xhr在某些平台上可能有问题。
2. 我个人认为xhr没有必要用池。除非你有足够证据证明创建xhr是很消耗资源的。

相关推荐

    简易封装Ajax.zip

    这个“简易封装Ajax.zip”文件包含了对Ajax进行简单封装的示例,通过`index.html`来展示调用,`myajax.js`作为封装的Ajax函数库,以及`getData.php`和`postData.php`作为服务器端处理数据的脚本。 首先,让我们详细...

    ajax封装实例代码

    在IT行业中,Ajax(Asynchronous JavaScript and XML)是一种在无需刷新整个网页的情况下,能够更新部分网页的技术。...了解并熟练掌握Ajax封装,对提升Web应用的用户体验和开发效率具有重要意义。

    Ajax的小封装 get,post请求

    在描述中提到了对Ajax的get请求的小封装,这意味着我们将会讨论如何用JavaScript来构建一个简易的Ajax GET请求函数,并可能涉及POST请求的实现。 ### 1. Ajax GET 请求小封装 GET请求是最常见的HTTP方法,用于从...

    JS封装的AJAX函数

    这里提到的"JS封装的AJAX函数"是将AJAX的基本操作整合到一个或多个JavaScript函数中,以便开发者可以更方便地调用和使用。下面我们将详细探讨AJAX的基本概念、工作原理以及封装后的使用方法。 首先,AJAX的核心是...

    原生js的AJAX封装以及实例展示.zip

    总的来说,原生JS的AJAX封装和实例展示了如何通过XMLHttpRequest对象与服务器进行交互,实现数据的动态加载和页面的无刷新更新,这对于构建交互性更强的Web应用至关重要。通过学习和实践这个例子,你可以更好地理解...

    XHR的简单封装xr.zip

    xr 是 XMLHttpRequest 的超简单封装,并返回 ES6 Promise。示例代码:xr.get('/api/items', {take: 5})  .then(res =&gt; console.log(res.data)); xr.post('/api/item', {name: 'hello'})  .then(res =&gt; ...

    AJAX简易教程及实例

    **AJAX简易教程及实例详解** AJAX(Asynchronous JavaScript and XML)是一种在不刷新整个网页的情况下,能够更新部分网页的技术。它通过在后台与服务器进行少量数据交换,使网页实现异步更新,提升了用户体验。...

    深入理解ajax系列第一篇之XHR对象

    XMLHttpRequest(XHR)对象是Ajax的核心,它首次由微软在IE5中引入,随后其他浏览器也实现了此功能。在IE5中,XHR是通过ActiveX对象MSXML实现的,而在IE7及以上版本以及Firefox、Chrome、Safari等现代浏览器中,它们...

    Ajax封装

    Ajax的核心是JavaScript对象XMLHttpRequest(XHR),它允许在后台与服务器进行通信。通过创建一个新的XHR对象,设置请求类型(GET或POST)、URL、是否异步以及发送的数据,然后调用send()方法发送请求。当服务器响应...

    ajax简易聊天室

    在聊天室的背景下,JSP用于处理用户的登录验证、消息存储以及用户状态管理等核心功能。 接着,我们来探讨Ajax的核心组成部分。Ajax由XMLHttpRequest对象(简称XHR)驱动,它是浏览器提供的一个API,允许JavaScript...

    没有XHR,Ajax精彩依旧

    Ajax的核心在于利用XMLHttpRequest对象进行异步数据交互,使用户在无需刷新整个页面的情况下,能够与服务器进行背景通信,提高网页的响应速度和用户体验。 **XMLHttpRequest (XHR)** XMLHttpRequest是Ajax的基础,...

    Ajax异步处理封装

    1. 创建XMLHttpRequest对象:在所有支持Ajax的浏览器中,首先我们需要创建一个XMLHttpRequest对象,它是Ajax的核心,负责与服务器进行通信。 2. 发起HTTP请求:通过XMLHttpRequest对象的open()方法指定HTTP请求类型...

    简单封装Ajax

    【简单封装Ajax】这篇文章主要探讨的是如何在JavaScript中对原生的XMLHttpRequest对象进行简单的封装,以便于在实际开发中更方便地进行异步数据请求。在Web开发中,Ajax(Asynchronous JavaScript and XML)是一种...

    ajaxTest 实用简单封装

    **AjaxTest 实用简单封装** Ajax(Asynchronous JavaScript and XML)技术是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。它通过在后台与服务器进行少量数据交换,使网页实现异步更新,大大提升了...

    JavaScript-初识ajax、ajax封装、及json简单实战案例(下).pdf

    Ajax的核心是XMLHttpRequest对象,它允许JavaScript在后台与服务器进行通信。通过创建XMLHttpRequest对象,设置HTTP请求方法(GET或POST)、URL以及请求头,然后调用open()和send()方法发送请求。当服务器响应时,...

    ajax设计方案封装库

    【标题】:Ajax设计方案封装库 在Web开发中,Ajax(Asynchronous JavaScript and XML)是一种在无需刷新整个页面的情况下,能够更新部分网页的技术。Ajax设计方案封装库是将这些复杂的交互逻辑进行抽象和封装,以便...

    xhr.base:使用xhr调用JQuery ajax

    xhr.base 是一个基于jQuery的库,它利用XMLHttpRequest对象(通常称为xhr)来实现Ajax功能。Ajax,全称Asynchronous JavaScript and XML,是一种在不重新加载整个网页的情况下更新部分网页内容的技术。xhr.base 库...

    简单ajax封装小工具

    这个“简单ajax封装小工具”可能是将常见的Ajax请求功能如GET、POST等进行了抽象和简化,方便开发者快速调用。通常,一个简单的Ajax封装可能包括以下组成部分: 1. **创建XMLHttpRequest对象**:这是Ajax的核心,...

Global site tag (gtag.js) - Google Analytics