设为首页 收藏本站
查看: 630|回复: 0

[经验分享] 为Ajax的XMLHttpRequest提供对象池(模仿Apache中ObjectPool的实现)

[复制链接]

尚未签到

发表于 2017-1-14 08:27:23 | 显示全部楼层 |阅读模式
在网上看到了有些同志提到了为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  ==  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;
        returnObject(object);
        destroyObject(object);
    }
     var  idlePool  =   this ._idlePool;
     for  ( var  i  =   0 ; i  <  idlePool.length; i ++ )  {
         var  object  =  idlePool;
        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 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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-328112-1-1.html 上篇帖子: Apache 2 mod_jk tomcat 5 双向SSL认证 传递证书信息 下篇帖子: “Apache Tomcat Tomcat5 服务因 0 (0x0) 服务性错误而停止”问题的解决
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表