最近做了个需求,后端返回商品信息给前端,但是信息中缺少图片地址,需要通过额外的接口获取。因为一个列表会展示多个商品,为了减少请求,需要收集页面展示商品的编码,在一定的时间后使用一个接口一次获取回来,并返回给各个请求来源。
class ImageManager {
private imageCache = new Map<string, string>();
private pendingRequests: { code: string; resolve: (url: string) => void; reject: (error: Error) => void }[] = [];
private batchTimer: number | null = null; // 修改为适合浏览器环境的类型标注
private readonly batchInterval = 500; // 批量请求的时间间隔,单位为毫秒
/**
* 异步获取图片URL
* @param {string} code - 图片code
* @returns {Promise<string>} 图片URL的Promise
*/
async getImageUrl(code: string): Promise<string> {
return new Promise((resolve, reject) => {
if (this.imageCache.has(code)) {
resolve(this.imageCache.get(code)!);
} else {
this.pendingRequests.push({ code, resolve, reject });
if (!this.batchTimer) {
this.batchTimer = window.setTimeout(() => this._processPendingRequests(), this.batchInterval); // 明确使用window对象
}
}
});
}
/**
* 处理待处理的图片请求
*/
private async _processPendingRequests() {
if (this.batchTimer) {
window.clearTimeout(this.batchTimer); // 明确使用window对象
}
this.batchTimer = null;
try {
const uniqueCodes = Array.from(new Set(this.pendingRequests.map(req => req.code)));
const fetchedImages = await this._batchFetch(uniqueCodes);
fetchedImages.forEach((url, code) => {
this.imageCache.set(code, url);
const request = this.pendingRequests.find(req => req.code === code);
if (request) {
request.resolve(url);
}
});
this.pendingRequests = [];
} catch (error) {
this.pendingRequests.forEach(req => req.reject(error));
this.pendingRequests = [];
console.error('Failed to fetch images batch:', error);
}
}
/**
* 模拟批量获取图片URL的网络请求
* @param {Array<string>} codes - 需要获取的图片code数组
* @returns {Promise<Map<string, string>>} 返回一个映射,键为图片code,值为图片URL
*/
private async _batchFetch(codes: string[]): Promise<Map<string, string>> {
// 实际应用中,这里应该替换为真实的API调用
const mockResponse = new Map(codes.map(code => [code, `https://example.com/images/${code}.jpg`]));
return new Promise(resolve => setTimeout(() => resolve(mockResponse), 1000)); // 模拟延迟
}
}
export const imageManager = new ImageManager();
网友评论