基于Promise的图片预加载

场景示例:

  1. 图片轮播:在网站上,有些页面可能有一个图片轮播,如果以用户端的网络环境较差,图片加载不及时,用户可能会看到空白或者加载中的状态。为了避免这种情况,你可以在显示轮播之前预加载所有的图片。
  2. 图片墙或相册:如果你在做一个图片墙或者相册功能,其中含有大量图片,直接加载可能会消耗大量的网络资源且用户体验较差,所以你可以选择部分加载(比如先加载所有可视区域内的图片),然后当用户滚动查看更多时,再按需加载。
  3. 游戏开发:在HTML5游戏中,通常我们需要预加载游戏的所有资源,包括图片、音频等。这时,我们也需要用到这样的预加载功能。 总的来说,在任何你希望提前获取资源,提升用户体验的场合,都可以使用这样的预加载技术。

方法:

loadImage 这是一个根据图片链接加载图片的函数,它返回一个Promise对象。当创建Promise对象时,我们创建一个Image对象,并设置它的src属性为我们提供的图片链接img。然后我们为Image对象添加两个事件处理器:onload和onerror。当图片加载成功时,onload事件处理器会被调用,然后调用resolve函数将Promise状态改为已解决,并且返回图片的链接。如果图片加载失败,onerror事件处理器会被调用,然后调用reject函数将Promise状态改为已拒绝,并返回图片链接。

js 复制代码
    loadImage(img) {
      return new Promise(function(resolve, reject) {
        const image = new Image()
        image.src = img
        image.onload = function() {
          resolve(image.src)
        }
        image.onerror = function() {
          reject(image.src)
        }
      })
    },

loadNextImages 这是一个加载一批(本例中是5个)图片的函数。首先,我们从全部图片列表imgTotalList中切割出前5个或剩下的所有图片(如果不足5个),存入nextImagesList。然后,我们为nextImagesList中的每一个图片链接创建一个Promise(通过调用loadImage(img)函数),并将这些Promise存入promises数组。然后我们调用Promise.all(promises)。Promise.all()方法返回一个Promise,它在所有给定的Promise都被解决后解决,或在任意一个Promise被拒绝后拒绝。当所有图片都加载成功,我们将nextImagesList中的图片链接添加到需要显示的图片列表loadlist中,并判断是否还有更多的图片需要加载,如果有,我们调用loadNextImages()继续加载下一批图片。如果有任何图片加载失败,我们在控制台打印错误信息。

js 复制代码
    loadNextImages() {
      // 每次截取最前面的五个
      const nextImagesList = this.imgTotalList.splice(
        0,
        Math.min(this.loadNum, this.imgTotalList.length)
      )
      const promises = []
      for (const img of nextImagesList) {
        promises.push(this.loadImage(img))
      }
      Promise.all(promises)
        .then(() => {
          this.loadlist.push(...nextImagesList)
          if (this.imgTotalList.length > 0) {
            this.loadNextImages()
          }
        })
        .catch(e => {
          console.error('Error loading images:', e)
        })
    },

例子:

vue2实现

js 复制代码
<template>
    <div class="book-list">
      <img
        v-for="img in loadlist"
        :src="img"
        :key="img"
        alt="img"
        width="50"
        height="50"
      />
    </div>
</template>

<script>
import bookList from './data.json'
export default {
  name: 'TextbookList',
  data() {
    return {
      loadlist: [],
      loadNum: 5,
      imgTotalList: [], // 这里放置你所有的图片路径
    }
  },
  mounted() {
    this.loadNextImages()
  },
  methods: {
    loadImage(img) {
      return new Promise(function(resolve, reject) {
        const image = new Image()
        image.src = img
        image.onload = function() {
          resolve(image.src)
        }
        image.onerror = function() {
          reject(image.src)
        }
      })
    },
    loadNextImages() {
      // 每次截取最前面的五个
      const nextImagesList = this.imgTotalList.splice(
        0,
        Math.min(this.loadNum, this.imgTotalList.length)
      )
      const promises = []
      for (const img of nextImagesList) {
        promises.push(this.loadImage(img))
      }
      Promise.all(promises)
        .then(() => {
          this.loadlist.push(...nextImagesList)
          if (this.imgTotalList.length > 0) {
            this.loadNextImages()
          }
        })
        .catch(e => {
          console.error('Error loading images:', e)
        })
    },
  },
}
</script>

<style lang="scss" scoped>
</style>
相关推荐
纽格立科技1 分钟前
DRM 发射端链路图(上)
前端·人工智能·车载系统·信息与通信·传媒
云水一下14 分钟前
Vue.js从零到精通系列(七):高级特性实战——Teleport、异步组件、自定义指令与TypeScript深度结合
前端·vue.js·typescript
qq43569470116 分钟前
Vue05
前端·vue.js
qq_4221525719 分钟前
PDF 解密工具怎么选?2026 年文档密码移除方案与注意事项
java·前端·pdf
YHHLAI22 分钟前
前端工程化调用 AI 多模态生图模型:Qwen Image Demo 实战
前端·人工智能
To_OC35 分钟前
我一直以为 Ajax 是个黑盒,直到我写了这 50 行代码
前端·后端·全栈
用户0595401744640 分钟前
RAG 记忆层踩坑实录:用户偏好凭空消失,我排查了 4 小时,最后用 LangChain + Chroma 搭了套自动化回归测试
前端·css
程序猿阿伟1 小时前
《Chrome隔离机制的维度落地指南》
前端·chrome
用户054324329701 小时前
AI 生成的代码怎么在前端安全预览 + 一键运行:sandbox iframe 实战 🔒
前端
ALianBlank1 小时前
一个 Unity 框架能做多少事?86 个模块 + 21 个小游戏平台
前端·后端·游戏开发