Promise 加载图片

使用 Promise 封装图片加载,处理成功和失败状态

问题

使用 Promise 封装图片加载功能,实现异步加载图片并处理加载成功或失败的情况。

解答

基础实现

function loadImage(url) {
  return new Promise((resolve, reject) => {
    // 创建 Image 对象
    const img = new Image()
    
    // 加载成功
    img.onload = () => {
      resolve(img)
    }
    
    // 加载失败
    img.onerror = () => {
      reject(new Error(`图片加载失败: ${url}`))
    }
    
    // 设置 src 触发加载
    img.src = url
  })
}

// 使用示例
loadImage('https://example.com/image.png')
  .then(img => {
    document.body.appendChild(img)
    console.log('图片尺寸:', img.width, img.height)
  })
  .catch(err => {
    console.error(err.message)
  })

带超时的实现

function loadImageWithTimeout(url, timeout = 5000) {
  return new Promise((resolve, reject) => {
    const img = new Image()
    
    // 超时定时器
    const timer = setTimeout(() => {
      reject(new Error(`图片加载超时: ${url}`))
    }, timeout)
    
    img.onload = () => {
      clearTimeout(timer)
      resolve(img)
    }
    
    img.onerror = () => {
      clearTimeout(timer)
      reject(new Error(`图片加载失败: ${url}`))
    }
    
    img.src = url
  })
}

批量加载图片

function loadImages(urls) {
  const promises = urls.map(url => loadImage(url))
  return Promise.all(promises)
}

// 使用示例
const urls = [
  'https://example.com/1.png',
  'https://example.com/2.png',
  'https://example.com/3.png'
]

loadImages(urls)
  .then(images => {
    images.forEach(img => document.body.appendChild(img))
  })
  .catch(err => {
    console.error('有图片加载失败:', err.message)
  })

使用 async/await

async function displayImage(url) {
  try {
    const img = await loadImage(url)
    document.body.appendChild(img)
    return img
  } catch (err) {
    console.error(err.message)
    // 可以返回占位图
    return null
  }
}

关键点

  • new Image() 创建图片对象,设置 src 触发加载
  • onload 回调在加载成功时触发,调用 resolve
  • onerror 回调在加载失败时触发,调用 reject
  • 批量加载使用 Promise.all,任一失败则整体失败
  • 实际项目中应考虑超时处理和重试机制