javascript 构建一个xmlhttp对象池合理创建和使用xmlhttp对象

如果我们在客户端频繁使用ajax技术,那么我们就不得不多次创建xmlhttp对象。当然,如您所知,我们可以改进创建的方式,比如使用全局变量来缓存一个实例(客户端的单例模式?!),对于同步方式的通信,这是很有效的,但是这样的方式对于异步通信会出现问题,因为没有了进程的堵塞,用户可能在上一次通信未完成时再次调用同一个xmlhttp实例,这样不等前一个调用的回调函数触发,前一次调用就被“覆盖”掉了(也就代表前一次调用失败)。建立一个保持xmlhttp实例的池,好处显而易见,最明显的优点就是我们不会创建冗余对象,同时也不会出现在同一个正在被调用的xmlhttp实例上出现再次被操作的情况。

具体实现思路:
我们使用一个数组来存储已创建的xmlhttp对象实例,然后每次调用从池中去取一个实例。xmlhttp实例通讯完毕后我们不用做任何处置,因为它自身的readyState属性可以标识出它是否可用,如果当时没有空闲的xmlhttp实例,且池中的实例数小于最大实例个数,那么就创建一个新的实例并放入池中。重新改进的实现代码如下:


代码如下:

//封装XMLHTTP的MyAjaxObj类
var MyAjaxObj = new Object();
var maxXmlHttpCount = 5; //最多5个xmlhttp对象存在

MyAjaxObj.reqList = []; //可以清空里面的项

MyAjaxObj.getFreeObj = function() {
var req = null;
var len = this.reqList.length;
//先从当前的池里取
for (var i = 0; i < len; i++) {
if (this.reqList[i]) {
if (this.reqList[i].readyState == 4 || this.reqList[i].readyState == 0) {
req = this.reqList[i];
break;
}
}
}
//如果没有闲置的对象,自己独立创建
if (req == null) {
if (this.reqList.length < maxXmlHttpCount) {
req = getXmlHttp();
this.reqList.push(req);
}
}
return req;
}

//创建一个XMLHTTP对象,兼容不同的浏览器
function getXmlHttp() {
var xmlHttp = false;
var arrSignatures = ["MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"];
for (var i = 0; i < arrSignatures.length; i++) {
try {
xmlHttp = new ActiveXObject(arrSignatures[i]);
return xmlHttp;
}
catch (oError) {
xmlHttp = false; //ignore
}
}
// throw new Error("MSXML is not installed on your system.");
if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
xmlHttp = new XMLHttpRequest();
}
return xmlHttp;
}

/*封装XMLHTTP向服务器发送请求的操作
url:向服务器请求的路径;method:请求的方法,即是get/post;***callback:当服务器成功返回结果时,调用的函数(类似c#回调函数)***
data:向服务器请求时附带的数据;urlencoded:url是否编码;cached:是否使用缓存; callBackError;当服务器返回错误时调用的函数
*/
MyAjaxObj.send = function(url, method, callback, data, urlencoded, cached, callBackError) {
var req = this.getFreeObj(); //从池里或者直接实例化一个XMLHTTP的实例

//当XMLHTTP的请求状态发生改变时调用 (核心处理函数)
req.onreadystatechange = function() {
// 当请求已经加载

if (req.readyState == 4) {
// 当请求返回成功
if (req.status == 200) { //或者 req.status < 400
// 当定义了成功回调函数时,执行成功回调函数
if (callback)
callback(req, data);
}
// 当请求返回错误

else {
//当定义了失败回调函数时,执行失败回调函数
if (callBackError)
callBackError(req, data);
}

// 有池的管理,我们可以省却释放资源的方法
// try {
// delete req;
// req = null;
// }
// catch (e) {
// alert(e.message);
// }
}
}

//如果以POST方式回发服务器
if (method.toUpperCase() == "POST") {
req.open("POST", url, true);
//请求是否需要缓存(只有在req.open之后才可以设置此项)
if (cached)
req.setRequestHeader("If-Modified-Since", "0");
//请求需要编码
if (urlencoded)
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send(data);
MyAjaxObj.reqList.push(req);
}
//以GET方式请求
else {
req.open("GET", url, true);
//请求是否需要缓存
if (cached)
req.setRequestHeader("If-Modified-Since", "0");
req.send(null);
MyAjaxObj.reqList.push(req);
}
return req;
}

//全部清除XMLHTTP数组元素,释放资源
MyAjaxObj.clearReqList = function() {
var len = MyAjaxObj.reqList.length;
for (var i = 0; i < len; i++) {
var req = MyAjaxObj.reqList[i];
if (req) {
try {
delete req;
} catch (e) { }
}
}
MyAjaxObj.reqList = [];
}

//进一步封装XMLHTTP以POST方式发送请求时的代码
//isClear:是否清除XMLHTTP数组的所有元素;其他参数的意义见 MyAjaxObj.send
MyAjaxObj.sendPost = function(url, data, callback, isClear, isCached, callBackError) {
if (isClear) {
MyAjaxObj.clearReqList();
}
MyAjaxObj.send(url, "POST", callback, data, true, isCached, callBackError); //post方法需要编码
}
//进一步封装XMLHTTP以GET方式发送请求时的代码
MyAjaxObj.sendGet = function(url, args, callback, isClear, isCached, callBackError) {
if (isClear)
MyAjaxObj.clearReqList();
return MyAjaxObj.send(url, "GET", callback, args, false, isCached, callBackError);
}

最后再ps:上周周末和一个哥们聊天的时候谈到ajax应用中的xmlhttp对象。那哥们ms很“虔诚”地问我说xmlhttp怎么就异步通信了。我当时竟然毫不思索地说因为这个对象处理我们的请求调用是“异步”的(当然可以设置成同步的,不过这是一句废话),当前这个请求不会影响其他的操作。这个回答是很“官方”的,显然没有说到问题的本质。哥们,您的眼神儿有必要那么bs人么?现在稍作分析,个人认为其实每个xmlhttp异步请求都会触发一个回调函数,这个回调函数的调用不影响其他的操作,这个方法才是“异步”。如果对比c#里的异步处理回调方法,它们在原理上其实是相通的。 哈哈,现在终于想通了, 真是太骄傲,太有出息了,想到就兴奋!

(0)

相关推荐

  • javascript XMLHttpRequest对象全面剖析

    一. 引言 异步JavaScript与XML(AJAX)是一个专用术语,用于实现在客户端脚本与服务器之间的数据交互过程.这一技术的优点在于,它向开发者提供了一种从Web服务器检索数据而不必把用户当前正在观察的页面回馈给服务器.与现代浏览器的通过存取浏览器DOM结构的编程代码(JavaScript)动态地改变被显示内容的支持相配合,AJAX让开发者在浏览器端更新被显示的HTML内容而不必刷新页面.换句话说,AJAX可以使基于浏览器的应用程序更具交互性而且更类似传统型桌面应用程序. Google的G

  • Java如何实现HTTP断点续传功能

    (一)断点续传的原理 其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已. 打个比方,浏览器请求服务器上的一个文时,所发出的请求如下: 假设服务器域名为wwww.sjtu.edu.cn,文件名为down.zip. GET /down.zip HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms- excel, application/msword, a

  • javaScript如何生成xmlhttp

    复制代码 代码如下: function ajaxFunction(){ var xmlHttp; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { try {// Internet Explorer xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new Active

  • java使用httpclient发送post请求示例

    复制代码 代码如下: package org.ssi.util; import java.io.IOException;import java.util.ArrayList;import java.util.List; import net.sf.json.JSONArray; import org.apache.commons.lang.exception.ExceptionUtils;import org.apache.commons.logging.Log;import org.apach

  • 使用flex中的httpservice方法与java进行交互

    地球已经调至震动状态使用flex中的httpservice方法与java进行交互: 一.写服务器: 1.在myeclipse中建立web项目 2.写一个用来打印xml的servlet 3.当使用httpservice与java进行交互的时候不用改写remoting-config.xml文件 4.web.xml文件中配置servlet的访问地址(一般不用配置,当一个servlet建好之后myeclipse就会自动配置好web.xml文 件,不用去改动,但是需要注意的是,当你在导入blazeds开发

  • java使用http实现文件下载学习示例

    复制代码 代码如下: package com.hongyuan.test; import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import

  • javascript一个无懈可击的实例化XMLHttpRequest的方法

    复制代码 代码如下: function getHTTPRequest() { var xhr = false; if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); //IE除外的浏览器 else if (window.ActiveXObject) { try { xhr = new ActiveXObject("Msxm12.XMLHTTP");//最新版的ActiveX对象 } catch(e) { try { xhr = n

  • JavaScript下通过的XMLHttpRequest发送请求的代码

    使用XMLHttpRequest对象分为4部完成: 1.创建XMLHttpRequest组建 2.设置回调函数 3.初始化XMLHttpRequest组建 4.发送请求 实例代码: 复制代码 代码如下: var userName; var passWord; var xmlHttpRequest; //XmlHttpRequest对象 function createXmlHttpRequest(){ if(window.ActiveXObject){ //如果是IE浏览器 return new

  • 使用java实现http多线程断点下载文件(二)

    下载工具我想没有几个人不会用的吧,前段时间比较无聊,花了点时间用java写了个简单的http多线程下载程序,纯粹是无聊才写的,只实现了几个简单的功能,而且也没写界面,今天正好也是一个无聊日,就拿来写篇文章,班门弄斧一下,觉得好给个掌声,不好也不要喷,谢谢! 我实现的这个http下载工具功能很简单,就是一个多线程以及一个断点恢复,当然下载是必不可少的.那么大概先整理一下要做的事情: 1.连接资源服务器,获取资源信息,创建文件 2.切分资源,多线程下载 3.断点恢复功能 4.下载速率统计 大概就这几

  • javascript对XMLHttpRequest异步请求的面向对象封装

    复制代码 代码如下: function CallBackObject() { this.XmlHttp = this.GetHttpObject(); } CallBackObject.prototype.GetHttpObject = function() //动态为CallBackObject的原型添加了GetHttpObject共有方法 { //第一步:创建XMLHttpRequest对象 //进行兼容性判断 var xmlhttp; /*@cc_on @if (@_jscript_ver

  • java使用httpclient模拟post请求和get请求示例

    复制代码 代码如下: import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;import org.apache.commons.httpclient.Header;import org

  • Javascript+XMLHttpRequest+asp.net无刷新读取数据库数据

    复制代码 代码如下: /**//// <summary> /// 生成带CDATA的节点 /// </summary> /// <param name="xDocument">XmlDocument</param> /// <param name="elementName">元素名称</param> /// <param name="cdataValue">CDA

  • java实现轻量型http代理服务器示例

    复制代码 代码如下: package cn.liangjintang.httpproxy; import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.ServerS

  • 使用java实现http多线程断点下载文件(一)

    基本原理:利用URLConnection获取要下载文件的长度.头部等相关信息,并设置响应的头部信息.并且通过URLConnection获取输入流,将文件分成指定的块,每一块单独开辟一个线程完成数据的读取.写入.通过输入流读取下载文件的信息,然后将读取的信息用RandomAccessFile随机写入到本地文件中.同时,每个线程写入的数据都文件指针也就是写入数据的长度,需要保存在一个临时文件中.这样当本次下载没有完成的时候,下次下载的时候就从这个文件中读取上一次下载的文件长度,然后继续接着上一次的位

  • 使用asx3m与xstream配合解决flex与java利用httpservice传递xml数据问题

    后端也存在java user object类,利用xstream组件把list中的user对象序列化成xml数据.在flex端通过httpservice使用E4X format格式获取.刚开始自己准备通过e4x技术来解析xml,构造flex user object,类似这样的处理方式: 复制代码 代码如下: public function fromXML(currentNode:XML):void{ userID = new Number(currentNode.userID); userNam

  • 基于JAVA中Jersey处理Http协议中的Multipart的详解

    那么Http协议中的Multipart是个什么东东?下面是摘抄http协议1.1的一段话:在multipart entity(多部分实体)的例子中,一个或多个不同的数据集合并在一个单一的body(体)中,一个"multipart"(多部分)类型 field的(域)必须出现在实体的header(头域).body(体)必须包括一个或多个body part(体部分),每一个位于boundary(边界)定界符线之前,最后一个则跟着一个结束边界定界符线.在它的边界定界符线后,每一个体部分由头域.

  • JAVA发送HTTP请求,返回HTTP响应内容,应用及实例代码

    JDK 中提供了一些对无状态协议请求(HTTP )的支持,下面我就将我所写的一个小例子(组件)进行描述:首先让我们先构建一个请求类(HttpRequester ).该类封装了 JAVA 实现简单请求的代码,如下: 复制代码 代码如下: import java.io.BufferedReader;  import java.io.IOException;  import java.io.InputStream;  import java.io.InputStreamReader;  import

  • javascript创建createXmlHttpRequest对象示例代码

    复制代码 代码如下: var xmlHttp; function createXmlHttpRequest()    {        if(window.XMLHttpRequest)        {            xmlHttp=new XMLHttpRequest(); if(xmlHttp.overrideMimeType)                {                    xmlHttp.overrideMimeType("text/xml")

随机推荐