feat(图片缓存文件): 优化执行逻辑

This commit is contained in:
hzj 2026-03-06 19:09:52 +08:00
parent f3521f5917
commit 1cc0469872

View File

@ -11,14 +11,14 @@ class ImageCacheManager {
this.imageCacheName = `likei-images-v${this.currentImageVersion}` // OSS图片
this.assetCacheName = `likei-assets-v${this.currentImageVersion}` // 本地assets
this.maxCacheItems = 200 // 最大缓存数量(100张
this.maxCacheSize = 200 * 1024 * 1024 // 最大缓存大小(100MB
this.maxCacheItems = 200 // 最大缓存数量(200张
this.maxCacheSize = 200 * 1024 * 1024 // 最大缓存大小(200MB
this.currentImageCacheSize = 0 // 当前image缓存大小字节
this.currentAssetCacheSize = 0 // 当前asset缓存大小字节
this.pendingRequests = new Map() // { url: { promise, retries } }
this.requestScheduler = new Map() // 上层请求调度器: CORS 降级处理 Promise 或 error
this.pendingRequests = new Map() // 底层请求管理:包含重试次数 { url: { promise, retries } }
this.maxRetries = 3 // 最大重试次数
this.requestScheduler = new Map() // 请求调度器
this.init()
}
@ -319,6 +319,7 @@ class ImageCacheManager {
const { cache, cacheName } = await this.getCacheForUrl(normalizedUrl) // 选中对应缓存
// 尝试多种匹配方式
// 带配置的 Request 对象匹配:严格匹配具有特定 CORS 配置和凭证策略的缓存响应,确保请求模式一致
let cachedResponse = await cache.match(
new Request(normalizedUrl, {
mode: 'cors',
@ -326,10 +327,13 @@ class ImageCacheManager {
}),
)
// URL 字符串精确匹配:最基础的匹配方式,查找缓存中 URL 完全一致的请求记录
if (!cachedResponse) {
cachedResponse = await cache.match(normalizedUrl)
}
// 忽略查询参数的 URL 匹配
// 通过 urlObj.origin 和 urlObj.pathname 拼接生成 urlWithoutQuery去除查询参数如时间戳、token 等)后进行匹配。用于兼容同一资源因携带不同查询参数而导致 URL 不同,但实际资源内容相同的场景。
if (!cachedResponse) {
const urlObj = new URL(normalizedUrl)
const urlWithoutQuery = `${urlObj.origin}${urlObj.pathname}`
@ -361,13 +365,14 @@ class ImageCacheManager {
return URL.createObjectURL(blob)
}
// 3. 创建新的请求并记录到 pendingRequests
// 3. 请求和缓存都没有
// 1创建新的请求并记录到 pendingRequests
const loadPromise = this.createLoadPromise(normalizedSrc)
this.pendingRequests.set(normalizedSrc, {
promise: loadPromise,
retries: this.maxRetries,
retries: this.maxRetries, // 记录重试次数
})
// 2执行请求
try {
const result = await loadPromise
return result
@ -377,7 +382,7 @@ class ImageCacheManager {
}
}
// 请求调度器:确保所有请求统一管理
// 上层请求调度器:确保所有请求统一管理
async scheduleRequest(src) {
const normalizedSrc = this.normalizeUrl(src)
@ -400,32 +405,26 @@ class ImageCacheManager {
}
// 否则创建新请求并加入调度器
const requestPromise = this.loadImage(src).catch((error) => {
// 标记失败请求
this.requestScheduler.set(normalizedSrc, error)
throw error
})
this.requestScheduler.set(normalizedSrc, requestPromise)
const requestPromise = this.loadImage(src)
this.requestScheduler.set(normalizedSrc, requestPromise) // 不记录重试次数,只存 Promise
try {
const result = await requestPromise
return result
return await requestPromise
} finally {
// 清理调度器中的记录
this.requestScheduler.delete(normalizedSrc)
this.requestScheduler.delete(normalizedSrc) // 清理调度器中的记录
}
}
// 创建加载 Promise含重试逻辑
async createLoadPromise(src) {
const normalizedSrc = this.normalizeUrl(src)
// 冗余步骤(作为防御性编程)
// const normalizedSrc = this.normalizeUrl(src)
// 新增:检查是否已有相同请求正在进行
if (this.pendingRequests.has(normalizedSrc)) {
console.warn(`请求已存在,跳过重复加载: ${src}`)
return this.pendingRequests.get(normalizedSrc).promise
}
// // 新增:检查是否已有相同请求正在进行
// if (this.pendingRequests.has(normalizedSrc)) {
// console.warn(`请求已存在,跳过重复加载: ${src}`)
// return this.pendingRequests.get(normalizedSrc).promise
// }
const attemptLoad = async (retriesLeft) => {
try {