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