论坛首页 Web前端技术论坛

同一个页面有多个ajax功能的XMLHttpRequest(

浏览 9139 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-08-31  
同一个页面有多个ajax功能的XMLHttpRequest()的问题

var xmlHttp;

function createXMLHttpRequest() {
if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
}

如果xmlHttp为全局的,
那一个页面里有多个ajax功能时,也就是会多个地方用到createXmlHttp();
譬如同一个页面有添加、编辑功能,
如果用户先用了添加,在添加等待中,用户又点了编辑,那么编辑调用
createXmlHttp()时就会覆盖添加的xmlHttp,那么当添加的动作在服务器端
处理完成后,在添加里的回调用到的xmlHttp.responseXML所返回的数据就
不能返回期望的数据了,
如果xmlHttp是局部的,那怎么把局部的xmlHttp传到回调函数里呢?
   发表时间:2006-09-11  
刚在ajacn发了个贴,关于为XMLHttpRequest提供一个对象池。或许能帮到你,转贴如下:

在网上看到了有些同志提到了为Ajax的XMLHttpRequest提供一个对象池,也读了他们给出的实现代码。感觉不是特别理想,于是模仿apache的commons中的ObjectPool的思路写了一个简单的JavaScript版。
望指教:
function ObjectPool(poolableObjectFactory) {
	this._poolableObjectFactory = poolableObjectFactory;
	this._idlePool = []; 
	this._activePool = []; 
}
// 从对象池中租借一个对象,如果目前没有可用的空闲对象则通过poolableObjectFactory创建一个
// 既然是借的,用完记得一定要还哦!
ObjectPool.prototype.borrowObject = function() {
	var object = null;
	var idlePool = this._idlePool;
	var factory = this._poolableObjectFactory;
	if (idlePool.length > 0) {
		object = idlePool.pop();
	}
	else {
		object = factory.makeObject();
	}
	if (object != null) {
		this._activePool.push(object);
		if (factory.activateObject) {
			factory.activateObject(object);
		}
	}
	return object;
}
// 归还一个对象
ObjectPool.prototype.returnObject = function(object) {
	function indexOf(array, object) {
		for (var i = 0; i < array.length; i++) {
			if (array[i] == object) return i;
		}
		return -1;
	}
	if (object != null) {
		var activePool = this._activePool;
		var factory = this._poolableObjectFactory;		
		var i = indexOf(activePool, object);
		if (i < 0) return;		
		if (factory.passivateObject) {
			factory.passivateObject(object);
		}		
		activePool.splice(i, 1);
		this._idlePool.push(object);
	}
}
// 返回当前激活对象的个数
ObjectPool.prototype.getNumActive = function() {
	return this._activePool.length;
}
// 返回当前空闲对象的个数
ObjectPool.prototype.getNumIdle = function() {
	return this._idlePool.length;
}
// 销毁对象池及其中的所有对象
// 如果对象池中的对象需要析构。那么必须实现poolableObjectFactory中的destroyObject方法,同时保证ObjectPool的destroy方法在需要的时候被调用到(例如Window的unload事件中)。
ObjectPool.prototype.destroy = function() {
	var factory = this._poolableObjectFactory;
	function returnObject(object) {
		if (factory.passivateObject) {
			factory.passivateObject(object);
		}
	}
	function destroyObject(object) {
		if (factory.destroyObject) {
			factory.destroyObject(object);
		}
	}	
	var activePool = this._activePool;
	for (var i = 0; i < activePool.length; i++) {
		var object = activePool[i];
		returnObject(object);
		destroyObject(object);
	}
	var idlePool = this._idlePool;
	for (var i = 0; i < idlePool.length; i++) {
		var object = idlePool[i];
		destroyObject(object);
	}
	this._idlePool = null; 
	this._activePool = null; 
	this._poolableObjectFactory = null;
}

上面代码中ObjectPool的构造参数poolableObjectFactory的声明如下:
// 注意: 这只是说明,不是真正的代码!
var PoolableObjectFactory = {		
	makeObject: function() {}, // 创建一个新的对象。(必须声明)	
	
	activateObject: function(object) {}, // 当一个对象被激活时(即被借出时)触发的方法。(可选)
	
	passivateObject: function(object) {}, // 当一个对象被钝化时(即被归还时)触发的方法。(可选)
	
	destroyObject: function(object) {} // 销毁一个对象。(可选)		
};


结合XMLHttpRequest创建过程的简陋示例:
// 声明XMLHttpRequest的创建工厂
var factory = {		
	makeObject: function() {
		// 创建XMLHttpRequset对象
		// 注:这里的创建方法不够强壮,勿学!
		if (window.ActiveXObject){
			return new ActiveXObject("Microsoft.XMLHTTP");
		}
		else {
			return new XMLHttpRequest();
		}
	},			
	passivateObject: function(xhr) {
		// 重置XMLHttpRequset对象
		xhr.onreadystatechange = {};
		xhr.abort();
	}
};
var pool = new ObjectPool(factory); // 创建对象池
// ......
var xhr = pool.borrowObject(); // 获得一个XMLHttpRequest对象
xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
		// ......
		pool.returnObject(xhr); // 归还XMLHttpRequest对象
	}
};
xhr.open(method, url, true);
// ......


最后附上jsUnit的测试用例:
function test_pool() {
	var factory = {
		counter: 0,
		
		makeObject: function() {
			return {id: ++ this.counter};			
		},		
		
		activateObject: function(object) {
			object.activated = true;
		},
		
		passivateObject: function(object) {
			object.activated = false;			
		},
		
		destroyObject: function(object) {
			object.destroyed = true;			
		}
	};
	var pool = new ObjectPool(factory);
	// borrowObject object1
	var object1 = pool.borrowObject();
	assertEquals(object1.id, 1);
	assertTrue(object1.activated);
	assertEquals(factory.counter, 1);
	assertEquals(pool.getNumActive(), 1);
	assertEquals(pool.getNumIdle(), 0);
	// borrowObject object2
	var object2 = pool.borrowObject();
	assertEquals(object2.id, 2);
	assertTrue(object2.activated);
	assertEquals(factory.counter, 2);
	assertEquals(pool.getNumActive(), 2);
	assertEquals(pool.getNumIdle(), 0);
	// borrowObject object3
	var object3 = pool.borrowObject();
	assertEquals(object3.id, 3);
	assertTrue(object3.activated);
	assertEquals(factory.counter, 3);
	assertEquals(pool.getNumActive(), 3);
	assertEquals(pool.getNumIdle(), 0);
	// returnObject object2
	pool.returnObject(object2);
	assertFalse(object2.activated);
	assertEquals(factory.counter, 3);
	assertEquals(pool.getNumActive(), 2);
	assertEquals(pool.getNumIdle(), 1);
	// returnObject object3
	pool.returnObject(object3);
	assertFalse(object3.activated);
	assertEquals(pool.getNumActive(), 1);
	assertEquals(pool.getNumIdle(), 2);
	// returnObject object1
	pool.returnObject(object1);
	assertFalse(object1.activated);
	assertEquals(pool.getNumActive(), 0);
	assertEquals(pool.getNumIdle(), 3);		
	// destroy the pool
	pool.destroy();
	assertTrue(object1.destroyed);
	assertTrue(object2.destroyed);
	assertTrue(object3.destroyed);
}
0 请登录后投票
   发表时间:2006-10-18  
在添加等待中,可以把编辑按钮或链接灰掉,如果这个功能本是互斥的话。
0 请登录后投票
   发表时间:2006-10-18  
楼上的对象池实现也太复杂了吧,有太多JAVA代码的痕迹了,对于生存周期不长的浏览器端代码,下面的实现已经足够了:
var XReqPool = new Object();

// XMLHttpRequest pool globals
XReqPool.reqSpare = [];
XReqPool.reqMaxSpare = 8;

XReqPool.getRequest = function() {
    if (XReqPool.reqSpare.length > 0) {
        return XReqPool.reqSpare.pop();
    }
    return XReqPool.createRequest();
}

XReqPool.freeRequest = function(req) {
    if (XReqPool.reqSpare.length >= XReqPool.reqMaxSpare)
        delete req;
    XReqPool.reqSpare.push(req);
}

上面给出的是不完整的代码,另外,对于Object Reuse的问题,在IE上是有问题的,具体请看下面的URL:
http://radio.javaranch.com/pascarello/2006/03/30/1143735438047.html
作者就是《AJAX IN ACTION》的作者,另外有个家伙给出了一个简单的解决方案,我的实验结果是有效的,推荐给大家:
http://keelypavan.blogspot.com/2006/03/reusing-xmlhttprequest-object-in-ie.html
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics