refactor(image): optimize image processing with AsyncQueue

- Replaced the promise-based image processing with an AsyncQueue to manage concurrent tasks more efficiently.
- Improved error handling and logging during image size and metadata retrieval.
- Updated the addMultiple method in AsyncQueue to return a wait function for better task management.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2025-05-11 21:40:27 +08:00
parent 7229ccfb86
commit 7047b76f58
2 changed files with 35 additions and 34 deletions

View File

@@ -6,6 +6,7 @@ import { Injectable, Logger, OnModuleInit } from '@nestjs/common'
import { ConfigsService } from '~/modules/configs/configs.service'
import { pickImagesFromMarkdown } from '~/utils/pic.util'
import { AsyncQueue } from '~/utils/queue.util'
import { requireDepsWithInstall } from '~/utils/tool.util'
import { HttpService } from './helper.http.service'
@@ -41,8 +42,8 @@ export class ImageService implements OnModuleInit {
(originImages ?? []).map((image) => [image.src, { ...image }]),
)
const task = [] as Promise<ImageModel>[]
for (const src of newImages) {
const queue = new AsyncQueue(2)
const imageProcessingTasks = newImages.map((src) => async () => {
const originImage = oldImagesMap.get(src)
const keys = new Set(Object.keys(originImage || {}))
@@ -55,27 +56,27 @@ export class ImageService implements OnModuleInit {
)
) {
result.push(originImage)
continue
return
}
const promise = new Promise<ImageModel>((resolve) => {
try {
this.logger.log(`Get --> ${src}`)
this.getOnlineImageSizeAndMeta(src)
.then(({ size, accent, blurHash }) => {
const { size, accent, blurHash } =
await this.getOnlineImageSizeAndMeta(src)
const filename = src.split('/').pop()
this.logger.debug(
`[${filename}]: height: ${size.height}, width: ${size.width}, accent: ${accent}`,
)
resolve({ ...size, accent, src, blurHash })
})
.catch((error) => {
result.push({ ...size, accent, src, blurHash })
} catch (error) {
this.logger.error(`GET --> ${src} ${error.message}`)
const oldRecord = oldImagesMap.get(src)
if (oldRecord) {
resolve(oldRecord)
} else
resolve({
result.push(oldRecord)
} else {
result.push({
width: undefined,
height: undefined,
type: undefined,
@@ -83,16 +84,15 @@ export class ImageService implements OnModuleInit {
src: undefined,
blurHash: undefined,
})
})
}
}
})
task.push(promise)
}
const images = await Promise.all(task)
result.push(...images)
// Add all tasks to the queue and wait for completion
const wait = queue.addMultiple(imageProcessingTasks)
await wait()
// 老图片不要过滤,记录到列头
if (originImages) {
for (const oldImageRecord of originImages) {
const src = oldImageRecord.src

View File

@@ -34,6 +34,7 @@ export class AsyncQueue {
addMultiple(requests: (() => Promise<any>)[]) {
this.queue.push(...requests)
this.runNext()
const wait = this.runNext()
return async () => await wait
}
}