mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-04-03 15:08:25 +00:00
fix(chat): repair search result sender info
This commit is contained in:
@@ -3,9 +3,11 @@
|
||||
export class AvatarLoadQueue {
|
||||
private queue: Array<{ url: string; resolve: () => void; reject: (error: Error) => void }> = []
|
||||
private loading = new Map<string, Promise<void>>()
|
||||
private failed = new Map<string, number>()
|
||||
private activeCount = 0
|
||||
private readonly maxConcurrent = 3
|
||||
private readonly delayBetweenBatches = 10
|
||||
private readonly failedTtlMs = 10 * 60 * 1000
|
||||
|
||||
private static instance: AvatarLoadQueue
|
||||
|
||||
@@ -18,6 +20,9 @@ export class AvatarLoadQueue {
|
||||
|
||||
async enqueue(url: string): Promise<void> {
|
||||
if (!url) return Promise.resolve()
|
||||
if (this.hasFailed(url)) {
|
||||
return Promise.reject(new Error(`Failed: ${url}`))
|
||||
}
|
||||
|
||||
// 核心修复:防止重复并发请求同一个 URL
|
||||
const existingPromise = this.loading.get(url)
|
||||
@@ -31,13 +36,40 @@ export class AvatarLoadQueue {
|
||||
})
|
||||
|
||||
this.loading.set(url, loadPromise)
|
||||
loadPromise.finally(() => {
|
||||
this.loading.delete(url)
|
||||
})
|
||||
void loadPromise.then(
|
||||
() => {
|
||||
this.loading.delete(url)
|
||||
this.clearFailed(url)
|
||||
},
|
||||
() => {
|
||||
this.loading.delete(url)
|
||||
}
|
||||
)
|
||||
|
||||
return loadPromise
|
||||
}
|
||||
|
||||
hasFailed(url: string): boolean {
|
||||
if (!url) return false
|
||||
const failedAt = this.failed.get(url)
|
||||
if (!failedAt) return false
|
||||
if (Date.now() - failedAt > this.failedTtlMs) {
|
||||
this.failed.delete(url)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
markFailed(url: string) {
|
||||
if (!url) return
|
||||
this.failed.set(url, Date.now())
|
||||
}
|
||||
|
||||
clearFailed(url: string) {
|
||||
if (!url) return
|
||||
this.failed.delete(url)
|
||||
}
|
||||
|
||||
private async processQueue() {
|
||||
if (this.activeCount >= this.maxConcurrent || this.queue.length === 0) {
|
||||
return
|
||||
@@ -49,13 +81,16 @@ export class AvatarLoadQueue {
|
||||
this.activeCount++
|
||||
|
||||
const img = new Image()
|
||||
img.referrerPolicy = 'no-referrer'
|
||||
img.onload = () => {
|
||||
this.activeCount--
|
||||
this.clearFailed(task.url)
|
||||
task.resolve()
|
||||
setTimeout(() => this.processQueue(), this.delayBetweenBatches)
|
||||
}
|
||||
img.onerror = () => {
|
||||
this.activeCount--
|
||||
this.markFailed(task.url)
|
||||
task.reject(new Error(`Failed: ${task.url}`))
|
||||
setTimeout(() => this.processQueue(), this.delayBetweenBatches)
|
||||
}
|
||||
@@ -67,6 +102,7 @@ export class AvatarLoadQueue {
|
||||
clear() {
|
||||
this.queue = []
|
||||
this.loading.clear()
|
||||
this.failed.clear()
|
||||
this.activeCount = 0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user