基于promise的图片资源一次性加载或预加载买得起光纤,不是每张图片都压缩得很小,有时候我们也想看高清大图,但是受限于网速,有时候场景是这样的:(很明显左边第一张图还没出来,其他的就出来了)图片资源预加载是一个很常见的需求。在web开发中,比如我们在开发基于canvas的游戏时,涉及到图片资源时,为了游戏体验,我们希望游戏只有在图片资源全部加载完毕后才开始。比如在一个有多个图片的网页上,因为图片太多或者图片太大,我们希望图片加载后一次显示,而不是一张一张的显示。这个时候我们也需要一次性使用图片加载功能。图片资源加载的原理是在浏览器向服务器发送请求的过程中。如果图片资源加载过一次,则不会再次从服务器加载相同的图片。利用这个原理,我们的实现思路是://创建一个Image对象letimg=newImage()img.src='imageaddress'//资源图片加载img.onload=function(){}基于这个原理,我封装了一个图片资源加载的函数,其结构如下/***@description图片资源加载函数*适用于canvas加载图片,返回一个promise异步对象,response的值为资源对象*@param{object}config参数设置,是一个对象*config.sourceData-资源对象{key:value}资源名称:资源地址*config.mode-默认为false,即使失败也会返回,mode为true,开启严格模式,所有失败都不会返回*config.target-要预加载的目标Node对象*config.response-默认false,是否返回一个promise异步对象,true为返回*@return{null||Promise}*/constloadImg=(config)=>{//初始化设置参数letsourceData=config.sourceDataletmode=config.mode||假让目标=config.target||[]让needRes=config.response||false//创建promise对象letpromise=newPromise((resolve,reject)=>{//functionInternal//完整代码在底部})}先来看看这个函数的强大之处吧!图片加载函数说明及使用显示函数loadImg()用于图片加载(函数实现代码在最下方),接受的参数是一个设置对象config,有4个参数键值config.sourceData:必填参数,资源对象{key:value}资源名称:资源地址config.target:可选参数,设置要加载的目标节点config.response:可选参数,默认false,不返回异步对象;设置为true,然后return,就可以使用then()进行下一步的数据操作了在此模式下加载,其余图片仍会显示值为true:启用严格模式。在此模式下,如果部分图片加载失败,则不会显示所有图片。如果需要返回结果,则返回结果将是错误的。基本调用方法如下//图片资源对象,对象的key值为自定义//如果此时有return,返回的response对象的key值与this相同letdata={img1:'http://plaechold.it/200x200',img2:'http://plaechold.it/200x200',img3:'http://plaechold.it/200x200'}//需要预加载的节点集合letimages=document.querySelectorAll('img')//开启资源加载loadImg({sourceData:data,//图片资源对象target:images,//预加载目标mode:true,//是否开启严格模式response:false//是否返回异步对象})加载应用实例canvas中的所有图片并绘制它们在画布面板中要记住config.response的值必须设置为true才能用于数据操作letcanvas=document.querySelector('canvas')letcontext=canvas.getContext('2d')//图像资源objectletdata={bird:'http://plaechold.it/200x200',//一张鸟的图片person:'http://plaechold.it/200x200',//一张人虎的图片:'http://解放军echod.it/200x200'//一只老虎的图片}//资源加载loadImg({sourceData:data,//图片资源对象mode:true,//是否开启严格模式response:true//返回一个异步对象,然后可以使用then获取结果进一步处理}).then(res=>{//res也是一个对象{bird:图像对象,person:图像对象,tiger:图像对象}//获取全部imageobjectsletimages=Object.values(res)images.forEach((value,index)=>{context.drawImage(value,index*100,index*100)})})//记得设置config的值.responsetotrueto使用then执行数据操作html页面加载后,一次显示所有图像实例>
