diff --git a/src/utils/image/imageCacheManager.js b/src/utils/image/imageCacheManager.js index ef874e3..3f839b5 100644 --- a/src/utils/image/imageCacheManager.js +++ b/src/utils/image/imageCacheManager.js @@ -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 {