|
Posted on 2006-09-08 17:47 BennyBao 閱讀(2487) 評論(3) 編輯 收藏 所屬分類: AJAX
在網(wǎng)上看到了有些同志提到了為Ajax的XMLHttpRequest提供一個對象池,也讀了他們給出的實現(xiàn)代碼。感覺不是特別理想,于是模仿apache的commons中的ObjectPool的思路寫了一個簡單的JavaScript版。望指教:
function
?ObjectPool(poolableObjectFactory)?
{
????
this
._poolableObjectFactory?
=
?poolableObjectFactory;
????
this
._idlePool?
=
?[];?
????
this
._activePool?
=
?[];?
}
//
?從對象池中租借一個對象,如果目前沒有可用的空閑對象則通過poolableObjectFactory創(chuàng)建一個
//
?既然是借的,用完記得一定要還哦!
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);
????}
}
//
?返回當前激活對象的個數(shù)
ObjectPool.prototype.getNumActive?
=
?
function
()?
{
????
return
?
this
._activePool.length;
}
//
?返回當前空閑對象的個數(shù)
ObjectPool.prototype.getNumIdle?
=
?
function
()?
{
????
return
?
this
._idlePool.length;
}
//
?銷毀對象池及其中的所有對象
//
?如果對象池中的對象需要析構(gòu)。那么必須實現(xiàn)poolableObjectFactory中的destroyObject方法,同時保證ObjectPool的destroy方法在需要的時候被調(diào)用到(例如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的構(gòu)造參數(shù)poolableObjectFactory的聲明如下:
//
?注意:?這只是說明,不是真正的代碼!
var
?PoolableObjectFactory?
=
?
{????????
 ????makeObject:?
function
()?
{}
,?
//
?創(chuàng)建一個新的對象。(必須聲明)????
????
 ????activateObject:?
function
(object)?
{}
,?
//
?當一個對象被激活時(即被借出時)觸發(fā)的方法。(可選)
????
 ????passivateObject:?
function
(object)?
{}
,?
//
?當一個對象被鈍化時(即被歸還時)觸發(fā)的方法。(可選)
????
 ????destroyObject:?
function
(object)?
{}
?
//
?銷毀一個對象。(可選)????????
}
;
結(jié)合XMLHttpRequest創(chuàng)建過程的簡陋示例:
//
?聲明XMLHttpRequest的創(chuàng)建工廠
var
?factory?
=
?
{????????
 ????makeObject:?
function
()?
{
????????
//
?創(chuàng)建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);?
//
?創(chuàng)建對象池
//
?
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.tkk7.com/Files/bennybao/pool.rar
Feedback
# re: 為Ajax的XMLHttpRequest提供對象池(模仿Apache中ObjectPool的實現(xiàn)) 回復(fù) 更多評論
2007-02-10 01:46 by
好
# re: 為Ajax的XMLHttpRequest提供對象池(模仿Apache中ObjectPool的實現(xiàn)) 回復(fù) 更多評論
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的實現(xiàn))[未登錄] 回復(fù) 更多評論
2007-02-16 13:57 by
@張沈鵬
activePool確實不是必須的,但是有了activePool之后就可以很方便的知道究竟有多少已激活的Object,或者可以利用一個類似“守護線程”的定時器來監(jiān)控每個Object的激活時間,以便與實現(xiàn)類似超時之類的功能。
另外需要說明的是,根據(jù)我的本意,這里的ObjectPool并不只為XMLHttp設(shè)計。
|