老师,我发现本节课中我们使用并发方式加载图片时,得到的图片顺序有可能和url数组的顺序不同,比如这样:
而按照url数组的顺序应该是这样:
请问我们应该如何在顾及效率的情况下(不要用继发)解决这个问题
登陆购买课程后可参与讨论,去登陆吧
同学你好,可以考虑在加载图片的时候,让其并发加载图片,此时只是在后台加载图片,并不需要将其追加显示到页面。然后结合Promise.all方法,再将加载的图片追加到页面中。示例:
祝学习愉快~
老师好!我试着按这样修改了一下,的确是可以实现按数组顺序加载显示图片的效果,但是发现进度条一上来就显示100%,最后所有图片都显示出来的时候消失。想问下这是因为改写之后loadImgAsync(url)是异步函数,前面又没有await,所以系统不会等待他执行完毕再执行下面的代码,而是在其加载时就先去执行了下面的done++和progress.update(),从而导致done一上来就是3,所以进度条一上来就显示100%吗?
想问下如果是这样的话,有没有什么好的办法可以解决这个问题呢?也就是让进度条能够随着图片加载进度而变化,而不是一上来就显示100%。
期待老师解答,谢谢~
同学你好, 问题解答如下:
1、理解是对的
2、可以考虑在图片加载成功事件中处理进度条解决这个小问题,参考下面的代码测试下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>页面加载进度条</title> <style> html, body, .progress { padding: 0; margin: 0; width: 100%; height: 100%; } img { max-width: 100%; } .progress { display: flex; justify-content: center; align-items: center; } .none { display: none; } </style> </head> <body> <div id="progress" class="progress">0%</div> <div id="content" class="none"></div> <script> function wait(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } // 全局定义done方便计算 let done = 0; // 多传参数 // function loadImgAsync(url) { function loadImgAsync(url, $el, total) { return new Promise((resolve, reject) => { const $img = new Image(); $img.addEventListener( "load", async () => { // await wait(1000); // 成功加载图片后将done值加一 done++; // 计算进度条 $el.innerHTML = `${parseInt((done / total) * 100)}%`; resolve($img); }, false ); $img.addEventListener( "error", () => { reject(new Error("Could not load image at " + url)); }, false ); $img.src = url; }); } class Progress { constructor($el) { this.$el = $el; } update(done, total) { this.$el.innerHTML = `${parseInt((done / total) * 100)}%`; } hide() { console.log("hide"); this.$el.classList.add("none"); } } (async () => { // const imgUrls = ['./ad.jpg', './ad_psyc.jpg', './logo.png']; const imgUrls = [ "https://img1.mydrivers.com/Img/20100731/08213345.jpg", "https://img1.mydrivers.com/Img/20100731/08230220.jpg", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg2.niutuku.com%2Fdesk%2F1208%2F2007%2Fntk-2007-25584.jpg&refer=http%3A%2F%2Fimg2.niutuku.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1654222356&t=c1a0d60776a99882cc8e22192c4b12c1", ]; const total = imgUrls.length; const $content = document.getElementById("content"); const $el = document.getElementById("progress"); const progress = new Progress($el); // const progress = new Progress(document.getElementById("progress")); // 并发 // 声明数组保存loadImgAsync方法调用返回的结果 const promiseArr = []; // 将其加入数组中,此时的loadImgAsync(url)是异步执行,也就意味着在并发加载图片 for (const url of imgUrls) { promiseArr.push(loadImgAsync(url, $el, total)); } // 结合Promise.all处理 const datas = await Promise.all(promiseArr); datas.forEach(($img) => { // 追加到页面 $content.appendChild($img); }); // await wait(1000); progress.hide(); $content.classList.remove("none"); })(); </script> </body> </html>
试了一下的确是可以解决进度条的问题了,感谢老师耐心解答!
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
登录后可查看更多问答,登录/注册
入行前端,是明智的选择!市场需求大,就业前景好,入行门槛低,小白易上手 全新升级:技术更新,Vue3.0/TypeScript/React17.x; 技术更全面,从0基础到全栈开发再到大型项目构建
157 1
75 1
31 2
200 5
155 1
在线咨询
领取优惠
免费试听
领取大纲
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星