前端队列收集编码,一次请求,分别返回结果给来源

最近做了个需求,后端返回商品信息给前端,但是信息中缺少图片地址,需要通过额外的接口获取。因为一个列表会展示多个商品,为了减少请求,需要收集页面展示商品的编码,在一定的时间后使用一个接口一次获取回来,并返回给各个请求来源。

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();
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容