需求的诞生:

先简单介绍一下业务场景,我们的项目是一个微博舆情分析系统,可以根据用户设置的关键字监测相关微博舆情,并进行实时推送。监测范围涵盖境内和境外微博平台(境内:新浪、腾讯,境外:twitter)。

因为访问境外的微博需要经过代理转发,导致经常有图片加载不出来,严重影响用户观感。此时就需要一个错误重试的处理,不要让界面上出现这个图片加载错误的图标,如下所示:

思路:

通过外部传进来的代表图片来源的参数,判断是否是境外图片。如果是,则先显示一张默认图片,等图片加载成功后再替换默认图片。如果图片加载错误了,间隔一段时间进行重试,直到加载成功,或失败次数大于设定的最大阈值时停止。

预备知识:

图片加载主要有三种状态:成功、失败、加载中(pendding),这个可以在控制台的NetWork里面看到。

Image对象有一个属性complete,可返回浏览器是否已完成对图像的加载。complete为true表示图片已经加载完成,为false则有两种情况,一是加载失败,而是正在加载中还没有结果。

开始撸:

先写一个函数,里面定义图片加载失败后的最大重试次数maxCount,初始化错误重试次数,并对图片url进行一个非空验证

/*** @param imageUrl  {string} 图片URL* @param callBack {function} 图片加载成功后的回调(参数:{imageUrl})*/
function loadImage(imageUrl, callBack) {if (!imageUrl) {return callBack({imageUrl: ''});}const maxCount = 5; // 最大重试次数let count = 0;      // 重试次数// 验证图片是否加载成功validateImage(imageUrl, callBack, maxCount, count);
}
复制代码

接下来就是核心代码validateImage函数的实现了, 首先定义好函数内部的变量

function validateImage(imageUrl, callBack, maxCount, count) {var img = new Image(),   // 创建一个image对象timeId,timer,finished,              // 图片加载成功标志位time = 40,             // 观察图片状态的定时器执行间隔timeCount = 0,         // 观察图片状态的定时器执行次数totalTime = 0,         // 观察图片状态的定时器累计执行时间errTimeout = 1000;     // 失败重试的延时
复制代码

然后给img.src赋值,此时图片就开始加载了

  img.src = imageUrl;count++;
复制代码

img.complete判断图片是否加载完毕,为true,则表示图片已加载成功,直接执行回调函将正确的图片路径返回

  if (img.complete) {callBack({imageUrl: imageUrl,});}
复制代码

如果img.complete为false,则需要分情况处理。

情况一:图片加载中(pendding状态),我们需要定时去看图片状态,直到图片加载成功或者失败,用onload事件或onerror事件去捕获。
然而这个地方有个大坑,什么坑呢?
图片有可能一直处于pendding状态,此时是不会有任何返回值的,所以没有办法用onloadonerr事件捕获,定时器一直重复执行,内存狂飙!

    else {if(totalTime < 60000){timeId = setTimeout(function () {timer();timeCount++;// 每次执行间隔是上次执行间隔的两倍time = 40*Math.pow(2,timeCount);totalTime += time;}, time);}else{clearTimeout(timeId);}}};// 执行观察定时器timeId = setTimeout(function () {timer();totalTime += time;}, time);
复制代码

此时如果图片加载成功或失败则会被onload捕获或onerr捕获。图片加载成功进入到onload里面,执行回调并将正确的图片路径返回;图片加载失败,进入到onerror里面,并进行重试,直到成功或者重试次数大于maxCount结束。

    img.onload = function () {clearTimeout(timeId);if (!finished) {return callBack({imageUrl: imageUrl});}};img.onerror = function () {if (count < maxCount) {clearTimeout(timeId);// 错误重试间隔每次以2s递增errTimeout += (count-1) * 2000;// 递归timeId = setTimeout(function () {validateImage(imageUrl, callBack, maxCount, count);}, errTimeout);} else {clearTimeout(timeId);if (!finished) {callBack({imageUrl: ''});}}};}
复制代码

ok,大功告成!

写的不好,仅供参考。谢谢大家

源码:

/*** 验证图片是否加载成功* @param imageUrl* @param callBack* @param maxCount {string} 最大轮询次数* @param count {string} 重新加载次数*/
function validateImage(imageUrl, callBack, maxCount, count) {let img = new Image(), timeId, timer, finished, time = 40, timeCount = 0, totalTime = 0, errTimeout = 1000;img.src = imageUrl;count++;if (img.complete) {callBack({imageUrl: imageUrl,});} else {timer = function () {if (img.width > 0 || img.height > 0) {finished = true;callBack({imageUrl: imageUrl});} else {if(totalTime < 60000){timeId = setTimeout(function () {timer();timeCount++;time = 40*Math.pow(2,timeCount);totalTime += time;}, time);}else{clearTimeout(timeId);}}};timeId = setTimeout(function () {timer();totalTime += time;}, time);img.onload = function () {clearTimeout(timeId);if (!finished) {return callBack({imageUrl: imageUrl});}};img.onerror = function () {if (count < maxCount) {clearTimeout(timeId);errTimeout += (count-1) * 2000;timeId = setTimeout(function () {validateImage(imageUrl, callBack, maxCount, count);}, errTimeout);} else {clearTimeout(timeId);if (!finished) {callBack({imageUrl: ''});}}};}
}/*** @param imageUrl  {string} 图片URL* @param callBack {function} 图片加载成功后的回调(参数:{imageUrl})* @returns {*}*/
function loadImage(imageUrl, callBack) {if (!imageUrl) {return callBack({imageUrl: ''});}const maxCount = 5;let count = 0;validateImage(imageUrl, callBack, maxCount, count);
}
export default loadImage;复制代码

转载于:https://juejin.im/post/5c5530cce51d457fff40fb3b

不需要任何依赖的图片加载错误处理的工具类load-image.js相关推荐

  1. Vue图片加载错误、图片加载失败的处理

    加载一个图片pic,会在代码里做一个检验图片是否存在,通常会像下面这样写 <img :src="pic?pic:'../assets/img/load.png'" alt=& ...

  2. 图片加载错误的处理 img.onerror

    在显示用户头像时,我们常常采用先加载后显示的策略,即在加载过程中显示loading.gif,待头像加载完成后再显示出来.这样做很好的提升了用户体验.但与此同时,偶尔也会出现一些问题,比如图片加载错误( ...

  3. img 图片加载错误时显示默认图片

    有时我们项目里的图片加载错误时(比如 404),为了友好体验,我们可以用一张默认图片来替代. 方法一:用 background 遮住原图片 <img src="no-such-pic. ...

  4. 关于图片加载错误的自定义处理(缺省图)

    缺省图的处理 以vue项目为例,当图片加载失败时,默认的样式不太行,可以做一个error处理,示例代码如下: <template><img :src="url" ...

  5. html 图片加载错误,CSS 无图片显示加载(失败)效果

    lazyload 时利用 iconfont 显示加载图片和加载失败效果 0. 效果 1. 显示加载中或者品牌图 可以是文字或者 iconfont, 并将图标显示到正中间 HTML 结构如下: .img ...

  6. img图片加载错误时显示默认图片

    JavaScript用的onerror事件,vue用的@error JavaScript写法 <img src="xxx" onerror="this.src='d ...

  7. 使用open3d加载点云数据工具类

    设计思路: 将点云文件加载成tensor类型,用于PointNet进行处理. 将tensor类型的点云文件保存到指定的位置 将点云数据可视化 类似于ply类型的点云文件,使用open3d读入之后,类型 ...

  8. uniapp图片加载错误,替换默认图,全网最简单的方案

    一句话解析:error时用v-if展示另一个image元素 核心代码: <image :src="imgUrl" v-if="!showErrImg" @ ...

  9. Android中常见的图片加载框架

    图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行 ...

最新文章

  1. 在CentOS7上部署Apache Mesos
  2. poj1503(高精度模拟加法)
  3. 出租房的网络环境研究
  4. kubernetes (1)基本概念
  5. 1805b: Coronavirus Spike Protein Binder Design 寻找蛋白质阻止新冠病毒感染人类细胞
  6. SVN服务器的搭建,它不是最全面的却是最详细易懂的~
  7. js 对象去除undefined_undefined和null区别
  8. 【啊哈!算法】之二、插入排序
  9. Net Core中数据库事务隔离详解——以Dapper和Mysql为例
  10. Visibiltity:none与Display:none区别
  11. 03-07 APP 控件交互
  12. 深度学习 目标检测 算法大全列表
  13. 十大排序算法----堆排序(最后一个非叶子节点的序号是n/2-1的推理)
  14. 利用局域网,传输文件
  15. [渝粤题库]西北工业大学离散数学
  16. JavaScript判断一个数是否为质数/素数
  17. 搭建自己的框架WedeNet(一)
  18. dw自动滚动图片_DW里怎么做图片自动播放
  19. [JZOJ5454]仔细的检查
  20. linux 扩展pam支持第三方认证

热门文章

  1. python列表切片口诀-切片 - 廖雪峰的官方网站
  2. php微信小程序向下滑动,微信小程序功能实现:上滑加载下拉刷新
  3. zookeeper代码浅析
  4. 题目1255:骰子点数概率(动态规划)
  5. LeetCode Ransom Note(字符串)
  6. protobuf的ParseFromArray 解析失败的问题
  7. Arcgis Server 默认服务端口号修改方法
  8. Scala(三):类
  9. 日报 18/07/22 您的设计模式!终于有时间开写~ ~
  10. bootstrap使用总结(导航在carousel居中之上)