欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

通過(guò)共享Promise解決前端重復(fù)請(qǐng)求的代碼示例

 更新時(shí)間:2025年03月17日 09:53:17   作者:wordbaby  
在處理前端重復(fù)請(qǐng)求問(wèn)題時(shí),通過(guò)共享?Promise?實(shí)現(xiàn)請(qǐng)求合并和結(jié)果復(fù)用是常見(jiàn)的高效解決方案,本文給大家介紹了詳細(xì)實(shí)現(xiàn)思路和代碼示例,需要的朋友可以參考下

一、問(wèn)題場(chǎng)景分析

當(dāng)出現(xiàn)以下情況時(shí),可能導(dǎo)致重復(fù)請(qǐng)求:

  • 用戶頻繁點(diǎn)擊觸發(fā)按鈕事件
  • 組件快速重復(fù)掛載/更新
  • 輸入框?qū)崟r(shí)搜索請(qǐng)求(如防抖失效)
  • 多個(gè)獨(dú)立組件同時(shí)加載相同數(shù)據(jù)

二、核心實(shí)現(xiàn)思路

  • 創(chuàng)建請(qǐng)求緩存池‌:存儲(chǔ)正在進(jìn)行的請(qǐng)求
  • 請(qǐng)求唯一標(biāo)識(shí)‌:通過(guò)參數(shù)生成請(qǐng)求唯一鍵
  • Promise 復(fù)用‌:相同請(qǐng)求返回緩存中的 Promise
  • 緩存清理機(jī)制‌:請(qǐng)求完成后自動(dòng)清理緩存

三、完整實(shí)現(xiàn)方案

1. 基礎(chǔ)版實(shí)現(xiàn)(ES6+)

// 請(qǐng)求緩存池
const requestCache = new Map();

function generateRequestKey(config) {
  return `${config.method}-${config.url}-${JSON.stringify(config.params)}`;
}

async function sharedRequest(config) {
  const requestKey = generateRequestKey(config);
  
  // 存在進(jìn)行中的相同請(qǐng)求
  if (requestCache.has(requestKey)) {
    return requestCache.get(requestKey);
  }

  // 創(chuàng)建新請(qǐng)求并緩存
  const requestPromise = axios(config)
    .then(response => {
      requestCache.delete(requestKey); // 成功清除緩存
      return response;
    })
    .catch(error => {
      requestCache.delete(requestKey); // 失敗也清除緩存
      throw error;
    });

  requestCache.set(requestKey, requestPromise);
  return requestPromise;
}

2. 高級(jí)功能增強(qiáng)版

class RequestPool {
  constructor() {
    this.pool = new Map();
    this.defaultTTL = 5000; // 默認(rèn)緩存5秒
  }

  getKey(config) {
    const { method, url, params, data } = config;
    return `${method}-${url}-${JSON.stringify(params)}-${JSON.stringify(data)}`;
  }

  async request(config) {
    const key = this.getKey(config);
    const now = Date.now();

    // 存在未過(guò)期的緩存
    if (this.pool.has(key)) {
      const { expire, promise } = this.pool.get(key);
      if (expire > now) return promise;
    }

    // 創(chuàng)建新請(qǐng)求
    const promise = axios(config).finally(() => {
      // 自動(dòng)清理或保留緩存
      if (!config.keepAlive) {
        this.pool.delete(key);
      }
    });

    // 緩存帶有效期
    this.pool.set(key, {
      promise,
      expire: Date.now() + (config.cacheTTL || this.defaultTTL)
    });

    return promise;
  }

  // 手動(dòng)清除緩存
  clearCache(key) {
    this.pool.delete(key);
  }
}

// 使用示例
const apiPool = new RequestPool();

function fetchUserData(userId) {
  return apiPool.request({
    method: 'GET',
    url: '/api/user',
    params: { id: userId },
    cacheTTL: 10000 // 自定義緩存時(shí)間
  });
}

四、關(guān)鍵點(diǎn)解析

1. 請(qǐng)求唯一標(biāo)識(shí)設(shè)計(jì)

  • 組合關(guān)鍵參數(shù)‌:method + url + 序列化后的params/data

  • 序列化優(yōu)化‌:

function stableStringify(obj) {
  const keys = Object.keys(obj).sort();
  return JSON.stringify(keys.map(k => ({ [k]: obj[k] })));
}

2. 緩存清理策略

策略類型實(shí)現(xiàn)方式適用場(chǎng)景
即時(shí)清理請(qǐng)求完成后立即刪除常規(guī)數(shù)據(jù)請(qǐng)求
TTL 過(guò)期檢查expire字段需要短期緩存的數(shù)據(jù)
手動(dòng)清理提供clearCache方法明確知道數(shù)據(jù)變更時(shí)
LRU 算法維護(hù)使用記錄+最大數(shù)量限制高頻請(qǐng)求且內(nèi)存敏感場(chǎng)景

3. 錯(cuò)誤處理要點(diǎn)

.catch(error => {
  // 特殊錯(cuò)誤處理:網(wǎng)絡(luò)錯(cuò)誤可保留短暫緩存
  if (error.isNetworkError) {
    setTimeout(() => this.pool.delete(key), 1000);
  }
  throw error;
});

五、適用場(chǎng)景對(duì)比

方案優(yōu)點(diǎn)缺點(diǎn)最佳使用場(chǎng)景
基礎(chǔ)版實(shí)現(xiàn)簡(jiǎn)單、內(nèi)存占用少缺乏高級(jí)控制簡(jiǎn)單頁(yè)面、少量API
類封裝版功能完善、擴(kuò)展性強(qiáng)實(shí)現(xiàn)復(fù)雜度較高中大型項(xiàng)目、復(fù)雜場(chǎng)景
第三方庫(kù)(swr)開(kāi)箱即用、功能豐富需要學(xué)習(xí)新API需要快速實(shí)現(xiàn)的復(fù)雜緩存需求

六、延伸優(yōu)化方向

  • 請(qǐng)求競(jìng)速處理‌:
let abortController;

function smartRequest() {
  if (abortController) {
    abortController.abort();
  }
  abortController = new AbortController();
  
  return fetch(url, { signal: abortController.signal });
}
  • 本地緩存融合‌:
const response = await request();
if (response.ok) {
  localStorage.setItem(cacheKey, {
    data: response.data,
    expire: Date.now() + 3600000
  });
}
  • 可視化監(jiān)控‌:
// 在RequestPool類中添加
getCacheStatus() {
  return Array.from(this.pool.entries()).map(([key, item]) => ({
    key,
    expireIn: item.expire - Date.now(),
    status: item.promise.isPending ? 'pending' : 'settled'
  }));
}

通過(guò)這種實(shí)現(xiàn)方式,可以有效解決以下問(wèn)題:

  • 減少 50%-90% 的重復(fù)網(wǎng)絡(luò)請(qǐng)求
  • 避免組件重復(fù)渲染造成的性能損耗
  • 保證多個(gè)組件間的數(shù)據(jù)一致性
  • 降低服務(wù)端并發(fā)壓力

實(shí)際項(xiàng)目中可根據(jù)具體需求選擇基礎(chǔ)版或增強(qiáng)版實(shí)現(xiàn),建議配合 TypeScript 進(jìn)行類型約束以保證代碼健壯性。

以上就是通過(guò)共享Promise解決前端重復(fù)請(qǐng)求的代碼示例的詳細(xì)內(nèi)容,更多關(guān)于共享Promise解決重復(fù)請(qǐng)求的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論