|
Posted on 2006-09-08 17:47 BennyBao 阅读(2474) 评论(3) 编辑 收藏 所属分类: AJAX
在网上看到了有些同志提到了为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);
}
下载:
http://www.blogjava.net/Files/bennybao/pool.rar
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设计。
|