为Ajax的XMLHttpRequest提供对象池(模仿Apache中ObjectPool的实现)
在网上看到了有些同志提到了为Ajax的XMLHttpRequest提供一个对象池,也读了他们给出的实现代码。感觉不是特别理想,于是模仿apache的commons中的ObjectPool的思路写了一个简单的JavaScript版。望指教:functionObjectPool(poolableObjectFactory){
this ._poolableObjectFactory=poolableObjectFactory;
this ._idlePool=[];
this ._activePool=[];
}
//从对象池中租借一个对象,如果目前没有可用的空闲对象则通过poolableObjectFactory创建一个
//既然是借的,用完记得一定要还哦!
ObjectPool.prototype.borrowObject= function (){
varobject= null ;
varidlePool= this ._idlePool;
varfactory= 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);
}
}
returnobject;
}
//归还一个对象
ObjectPool.prototype.returnObject= function (object){
functionindexOf(array, object){
for( vari= 0 ; i<array.length; i ++ ){
if(array==object)returni;
}
return - 1 ;
}
if(object!= null ){
varactivePool= this ._activePool;
varfactory= this ._poolableObjectFactory;
vari=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 (){
varfactory= this ._poolableObjectFactory;
functionreturnObject(object){
if(factory.passivateObject){
factory.passivateObject(object);
}
}
functiondestroyObject(object){
if(factory.destroyObject){
factory.destroyObject(object);
}
}
varactivePool= this ._activePool;
for( vari= 0 ; i<activePool.length; i ++ ){
varobject=activePool;
returnObject(object);
destroyObject(object);
}
varidlePool= this ._idlePool;
for( vari= 0 ; i<idlePool.length; i ++ ){
varobject=idlePool;
destroyObject(object);
}
this ._idlePool= null ;
this ._activePool= null ;
this ._poolableObjectFactory= null ;
}
上面代码中ObjectPool的构造参数poolableObjectFactory的声明如下:
//注意: 这只是说明,不是真正的代码!
varPoolableObjectFactory= {
makeObject:function (){} ,//创建一个新的对象。(必须声明)
activateObject:function (object){} ,//当一个对象被激活时(即被借出时)触发的方法。(可选)
passivateObject:function (object){} ,//当一个对象被钝化时(即被归还时)触发的方法。(可选)
destroyObject:function (object){} //销毁一个对象。(可选)
} ;
结合XMLHttpRequest创建过程的简陋示例:
//声明XMLHttpRequest的创建工厂
varfactory= {
makeObject:function (){
//创建XMLHttpRequset对象
if(window.ActiveXObject) {
return newActiveXObject( " Microsoft.XMLHTTP " );
}
else {
return newXMLHttpRequest();
}
} ,
passivateObject:function (xhr){
//重置XMLHttpRequset对象
xhr.onreadystatechange= {} ;
xhr.abort();
}
} ;
varpool= newObjectPool(factory);//创建对象池
//
varxhr=pool.borrowObject();//获得一个XMLHttpRequest对象
xhr.onreadystatechange= function (){
if(xhr.readyState== 4 ){
//
pool.returnObject(xhr);//归还XMLHttpRequest对象
}
} ;
xhr.open(method, url,true );
//
最后附上jsUnit的测试用例:
functiontest_pool(){
varfactory= {
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 ;
}
} ;
varpool= newObjectPool(factory);
//borrowObject object1
varobject1=pool.borrowObject();
assertEquals(object1.id,1 );
assertTrue(object1.activated);
assertEquals(factory.counter,1 );
assertEquals(pool.getNumActive(),1 );
assertEquals(pool.getNumIdle(),0 );
//borrowObject object2
varobject2=pool.borrowObject();
assertEquals(object2.id,2 );
assertTrue(object2.activated);
assertEquals(factory.counter,2 );
assertEquals(pool.getNumActive(),2 );
assertEquals(pool.getNumIdle(),0 );
//borrowObject object3
varobject3=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);
}
下载: http://www.blogjava.net/Files/bennybao/pool.rar
Feedback
# re: 为Ajax的XMLHttpRequest提供对象池(模仿Apache中ObjectPool的实现)回复更多评论
2007-02-10 01:46 by ghf
好
# re: 为Ajax的XMLHttpRequest提供对象池(模仿Apache中ObjectPool的实现)回复更多评论
2007-02-16 11:18 by 张沈鹏
为什么要一个activePool ,没有什么用处呀,用完了直接push进入idle,用的时候直接从idle中pop,同时把xmlrequest封装一下,让他自动来pop和push,用只要给出url和recall就可以了
我的邮箱是zsp007@gmail.com欢迎探讨
__reqPool={
idle:[],
new:function(){
var r=this.idle.pop();
if(!r){
if (window.XMLHttpRequest)r=new XMLHttpRequest();
else{
try{r=new ActiveXObject("Msxml2.XMLHTTP");}
catch(e){r=new ActiveXObject("Microsoft.XMLHTTP");}
}
}
return r;
}
open:function(url,recall,error){
var http=this.new();
http.open("GET",url,true);
http.onreadystatechange=function(){
if(http.readyState==4)
{
if(http.status==200)recall(http.responseText.toString());
else if(error) error(http.status,http.responseText.toString());
idle.push(http);
}
};
}
}
# re: 为Ajax的XMLHttpRequest提供对象池(模仿Apache中ObjectPool的实现)[未登录]回复更多评论
2007-02-16 13:57 by BennyBao
@张沈鹏
activePool确实不是必须的,但是有了activePool之后就可以很方便的知道究竟有多少已激活的Object,或者可以利用一个类似“守护线程”的定时器来监控每个Object的激活时间,以便与实现类似超时之类的功能。
另外需要说明的是,根据我的本意,这里的ObjectPool并不只为XMLHttp设计。
页:
[1]