手机版

使用imagepool的详细说明 一个JavaScript前端图像加载管理器

时间:2021-10-15 来源:互联网 编辑:宝哥软件园 浏览:

Imagepool是一个管理镜像加载的JS工具,可以通过imagepool控制并发镜像加载的次数。

加载图片最原始的方法是直接写一个img标签,比如img src='http: picture url'/。

经过不断优化,出现了图片延时加载的方案。这一次,图片的URL不是直接写在src属性中,而是写在一个属性中,比如img src=' http 3360 ' data-src=' http : picture URL '/。这样浏览器就不会自动加载图片了。当需要在适当的时候加载时,使用js将data-src属性中的url放入img标签的src属性中,或者在读取url后使用js加载图片,然后设置src属性显示图片。

看起来已经控制得很好了,但还是会有问题。

虽然只能加载一部分图片,但这部分图片可能还是一个比较大的数量级。

对于PC来说没什么大不了的,但是对于手机来说,并发加载的图片数量太大,可能会导致应用崩溃。

因此,我们迫切需要一种图片缓冲机制来控制图片的并发加载。类似于后端数据库连接池,它不仅可以创建太多的连接,而且可以充分重用每个连接。

至此,imagepool诞生了。

糟糕的原理图。

说明

首先初始化连接池:

var image pool=initi image pool(5);InitImagePool是一个全局方法,可以在任何地方直接使用。函数的作用是创建一个连接池,您可以指定连接池中的最大连接数,这是可选的,默认为5。

在同一个页面中,多次调用initImagePool都会返回同一个核心实例,它总是第一个,感觉就像一个单独的实例。例如:

复制代码如下: var imagepool 1=initi imagepool(3);var image pool 2=initi image pool(7);

此时,imagepool1和imagepool2之间的最大连接数为3,内部使用相同的核心实例。请注意,内部内核是相同的,而不是imagepool1===imagepool2。

初始化后,可以安全大胆地加载图片。

最简单的调用方法如下:

复制代码如下: var imagepool=initi imagepool(10);Imagepool.load ('picture URL ',{ success : function(src){ console . log(' success 3603360:3360 ' src);},error:函数(src){ console . log(' error :3360:33603: ' src);}});

直接在实例上调用load方法。

加载方法有两个参数。第一个参数是要加载的图片的url,第二个参数是各种选项,包括成功和失败的回调,回调时会传入图片的url。

这样只能介绍一张图片,所以也可以写成以下形式:

复制代码如下: var imagepool=initi imagepool(10);Imagepool.load([' picture1url ',' picture2url'],{ success : function(src){ console . log(' success 33603360: ' src);},error:函数(src){ console . log(' error :3360:33603: ' src);}});

通过传入一个图像url数组,可以传入多个图像。

每张图片加载成功(或失败),将调用success(或error)方法,并传入相应的图片url。

但有时我们不需要如此频繁的回调,所以我们传入一个图像url数组,当这个数组中的所有图像都被处理后,我们可以再次回调。

只需添加一个选项:

复制代码如下: var imagepool=initi imagepool(10);Imagepool.load([' picture1url ',' picture2url'],{success3360function (sarray,earray,count){ console . log(' sarray :336033603360 ' sarray);console . log(' eArray :33603360336033603: ' eArray);console . log(' count :33603360: ' count);},error:函数(src){ console . log(' error :3360:33603: ' src);},once : true });

通过向选项添加一次属性并将其设置为true,您只能回调一次。

这个回调将不可避免地回调成功方法,此时错误方法被忽略。

此时,回调成功方法不再传入图片url参数,而是传入三个参数,即成功的url数组、失败的url数组和处理的图片总数。

此外,还有另一种获取连接池内部状态的方法:

复制代码如下: var imagepool=initi imagepool(10);console . log(imagepool . info());

通过调用info方法,可以获得连接池当前的内部状态。数据结构如下:

Object.task.count连接池中等待处理的任务数Object.thread.count连接池中最大连接数Object.thread.free连接池中空闲连接数建议不要频繁调用此方法。

最后图片加载失败,最多试3次。如果加载最终失败,错误方法将被回调。尝试次数可以在源代码中修改。

最后,再次强调一下,读者可以随意将图片推送到连接池中,不用担心太多并发问题。imagepool将帮助您加载这些图片。

最后,必须说明的是,imagepool理论上不会降低图片的加载速度,只是轻轻加载。

源代码

复制代码代码如下:(函数(导出){ //单例定义变量实例=nullvar emptyFn=function(){ };//初始默认配置var config_default={ //线程池'线程'数量thread: 5,//图片加载失败重试次数//重试2次,加上原有的一次,总共是3次尝试' : 2 };//工具var _ helper={//设置数字正射影像图属性setattr :(function(){ var img=new Image();//判断浏览器是否支持HTML5数据集if(img . dataset){ 0返回函数(dom,名称,值){ DOM。数据集[名称]=值;返回值;};}else{返回函数(dom,名称,值){ DOM。SetAttribute(' data-' name,value);返回值;};} }()), //获取数字正射影像图属性getattr :(function(){ var img=new Image();//判断浏览器是否支持HTML5数据集if(img . dataset){ 0返回函数(dom,名称){ 0返回多姆。数据集[名称];};}else{ return函数(dom,name){ return DOM。GetAttribute(' data-' name);};} }()) };/** * 构造方法* @param max最大连接数。数值*/函数ImagePool(最大){ //最大并发数量这个。max=max | | config _ default。螺纹;this . LinkHead=null this . LinkNode=null//加载池//[{img: dom,free: true,node: node}] //node /} /** *初始化*/imagepool。原型。initpool=function(){ var I,img,obj,_ s;_s=这个;for(I=0;I this . MaXi){ obj={ };img=new Image();_助手。SetAttr(img,' id ',I);img.onload=function(){ var id,src//回调//_ s . GetNode(这个)。选项。成功。调用(null,this。src);_ s .注意(_ s . GetNode(this),‘成功’,这个。src);//处理任务_s.executeLink(此);};img。one rror=function(e){ var node=_ s . get node(this);//判断尝试次数if(节点。请尝试config _ default。try){ node。try=节点。尝试1;//再次追加到任务链表末尾_ s . appendnode(_ s . create node(节点。src,node.options,node.notice,node.group,node。尝试);} else {//错误回调//node.options.error.call(null,this。src);_ s .注意(节点,“错误”,这个。src);} //处理任务_s.executeLink(此);};obj.img=imgobj.free=truethis。游泳池。推送(obj);} };/** * 回调封装* @param节点节点。对象* @参数状态状态。字符串。可选值:成功(成功)|错误(失败)* @param src图片路径。字符串*/imagepool。原型。notice=function(节点,状态,src){ node.notice(状态,src);};/** * 处理链表任务* @param dom图像数字正射影像图对象。对象*/imagepool。原型。执行链接=函数(DOM){//判断链表是否存在节点if(this.linkHead){ //加载下一个图片this.setSrc(dom,this。LinkHead);//去除链表头这个。shift节点();}else{ //设置自身状态为空闲this.status(dom,true);} };/** * 获取空闲'线程*/imagepool。原型。getfree=function(){ var length,I;for(i=0,length=this。游泳池。长度;一、长度;i ){ if(this.pool[i].免费){ 0返回这个。池[I];} }返回null };/** * 封装科学研究委员会属性设置* 因为改变科学研究委员会属性相当于加载图片,所以把操作封装起来* @param dom图像数字正射影像图对象。对象* @param节点节点。对象*/imagepool。原型。setsrc=函数(DOM,节点){ //设置池中的'线程'为非空闲状态this.status(dom,false);//关联节点this.setNode(dom,node);//加载图片多姆。src=节点。src};/** * 更新池中的'线程'状态* @param dom图像数字正射影像图对象。对象* @参数状态状态。布尔。可选值:true(空闲)|false(非空闲)*/imagepool。原型。status=function(DOM,status){ var id=_ helper。getattr(DOM,' id ');this.pool[id].自由=状态;//空闲状态,清除关联的节点if(status){ this.pool[id].节点=null } }/** * 更新池中的'线程'的关联节点* @param dom图像数字正射影像图对象。对象* @param节点节点。对象*/imagepool。原型。setnode=function(DOM,node){ var id=_ helper。getattr(DOM,' id ');this.pool[id].节点=节点返回this.pool[id].node===node };/** * 获取池中的'线程'的关联节点* @param dom图像数字正射影像图对象。

对象*/imagepool。原型。get node=function(DOM){ var id=_ helper。getattr(DOM,' id ');返回this.pool[id].节点;};/** * 对外接口,加载图片* @param src可以是科学研究委员会字符串,也可以是科学研究委员会字符串数组* @param选项用户自定义参数。包含:成功回调、误差回调一次标识*/imagepool。原型。load=function(src,options){ var src=[],free=null,length=0,i=0,//只初始化一次回调策略注意=(function(){ if(options。一次){返回函数(状态,src){ var g=this.group,o=this.options//记录g[地位]。推送(src);//判断改组是否全部处理完成如果成功。长度g .错误。长度===g . count){//异步//实际上是作为另一个任务单独执行,防止回调函数执行时间过长影响图片加载速度setTimeout(function(){ o . success。调用(null,g.success,g.error,g . count);},1);} };}else{ return function(status,src){ var o=this。选项;//直接回调setTimeout(函数()o[状态])。调用(null,src);},1);};} }()),组={ count: 0,success: [],error: [] },节点=null options=options | | { };选项。成功=选项。成功| |空fn;选项。错误=选项。错误| | emptyFnsrc=src。concat(src);//设置组元素个数团体。计数=srcs。长度;//遍历需要加载的图片对于(i=0,长度=srcs.length一、长度;i ){ //创建节点节点=这个。创建节点(src[I],选项,通知,组);//判断线程池是否有空闲免费=这个。getfree();如果(免费){ //有空闲,则立即加载图片this.setSrc(free.img,node);}else{ //没有空闲,将任务添加到链表this.appendNode(节点);} } };/** * 获取内部状态信息* @返回{ { } } */imagepool。原型。info=function(){ var info={ },length=0,i=0,node=null//线程信息。线程={ };//线程总数量信息。线。计数=这个。游泳池。长度;//空闲线程数量信息。线。free=0;//任务信息。任务={ };//待处理任务数量信息。任务。计数=0;//获取空闲'线程'数量for(i=0,length=this。游泳池。长度;一、长度;i ){ if(this.pool[i].免费){信息。线。免费=信息。线。免费1;} } //获取任务数量(任务链长度)node=this . linkhead if(node){ info。任务。计数=信息。任务。计数1;while(节点。下一个){信息。任务。计数=信息。任务。计数1;节点=node.next} }返回信息;};/** * 创建节点* @param src图片路径。字符串* @param选项用户自定义参数。包含:成功回调、误差回调一次标识* @param通知回调策略。函数* @param组组信息。对象{count: 0,success: [],error: []} * @param tr出错重试次数。数值。默认为0。* @返回{ { } } */imagepool。原型。create node=function(src,options,notice,group,tr){ var node={ };node . src=src node . options=options node . notice=notice node . group=group node。try=tr | | 0;返回节点;};/** * 向任务链表末尾追加节点* @param节点节点。对象*/imagepool。原型。appendnode=函数(节点){//判断链表是否为空if(!这个。{这个。linkhead=节点;this.linkNode=node} else { this。linknode。next=节点;this.linkNode=node } }/** * 删除链表头*/imagepool。原型。shift节点=function(){//判断链表是否存在节点if(this.linkHead){ //修改链表头这个。LinkHead=这个。LinkHead。next | | null} };/** * 导出对外接口* @param max最大连接数。数值* @返回{{load: Function,info : Function } } */导出。初始图像池=函数(最大){ if(!实例){ instance=new ImagePool(最大值);实例。init pool();}返回{ /** *加载图片*/load:函数(){ instance.load.apply(实例,参数);}, /** * 内部信息* @返回{ * | any | void } */info : function(){ return instance。信息。调用(实例);} };};}(这个));

上面是一个如何使用这个奇妙的javascript前端图像加载管理器的例子。你学会使用它了吗?

版权声明:使用imagepool的详细说明 一个JavaScript前端图像加载管理器是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。