|  | 
				
					
	
		
			
 			Posted on 2006-09-08 17:47 BennyBao  阅读(2505) 评论(3)  编辑  收藏   所属分类: AJAX   
		
				在网上看到了有些同志提到了为Ajax的XMLHttpRequest提供一个对象池,也读了他们给出的实现代码。感觉不是特别理想,于是模仿apache的commons中的ObjectPool的思路写了一个简单的JavaScript版。望指教: 
 
						
								
										上面代码中ObjectPool的构造参数poolableObjectFactory的声明如下:   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
										
								
								
										; 
  } 
 
				
						
								结合XMLHttpRequest创建过程的简陋示例: //
								 注意: 这只是说明,不是真正的代码! 
    var
										 PoolableObjectFactory 
										=  { 
   makeObject: 
												function
												()  {}
												
												, 
												//
												 创建一个新的对象。(必须声明) 
   
   activateObject: 
												function
												(object)  {}
												
												, 
												//
												 当一个对象被激活时(即被借出时)触发的方法。(可选) 
   
   passivateObject: 
												function
												(object)  {}
												
												, 
												//
												 当一个对象被钝化时(即被归还时)触发的方法。(可选) 
   
   destroyObject: 
												function
												(object)  {}
												
												 
												//
												 销毁一个对象。(可选) 
  }
										
								
						
				
				
						
								
										; 
 
				
						
								最后附上jsUnit的测试用例: //
								 声明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
						
				
				
						
								); 
  //    
 
						
								
										下载: 
		
				http://www.blogjava.net/Files/bennybao/pool.rar   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); 
  } 
	    
    
Feedback
				
					
						# re: 为Ajax的XMLHttpRequest提供对象池(模仿Apache中ObjectPool的实现)  回复  更多评论
						  
					
					2007-02-10 01:46 by 
				 好 
				
					
						# 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 
				 @张沈鹏
activePool确实不是必须的,但是有了activePool之后就可以很方便的知道究竟有多少已激活的Object,或者可以利用一个类似“守护线程”的定时器来监控每个Object的激活时间,以便与实现类似超时之类的功能。
 另外需要说明的是,根据我的本意,这里的ObjectPool并不只为XMLHttp设计。
 
 |