实现前端多次调用接口时,只发送一次请求

252 阅读1分钟

前言

前端开发过程中,有时会碰到在某些页面或者组件里请求同一个接口,如果同时请求时,调用多次接口,会造成网络的浪费以及影响性能

比如获取token,通常是在请求拦截器里获取token,如果本地token不存在或者过期,则需要调用接口获取token,这时如果发送多个请求时,则获取token接口会请求多次

实现一个singleManage工具库

const singleManage = {
  cacheMap: {}, // 缓存数据
  statusMap: {}, // 状态,是否在请求中
  queueCallbacks: {}, // 队列,接口在请求中时,之后的请求则添加到队列中
  // 获取数据
  async getSourceData(params) {
    // 设置缓存key
    const cacheKey = JSON.stringify(params);
    // 存在缓存数据时,直接返回缓存的数据
    const cacheData = this.cacheMap[cacheKey]
    if (cacheData) return cacheData;
    if (this.statusMap[cacheKey]) {
      const result = await new Promise((resolve, reject) => {
        this.queueCallbacks[cacheKey] = this.queueCallbacks[cacheKey] || [];
        this.queueCallbacks[cacheKey].push({
          resolve,
          reject
        });
      });
      return result;
    }
    this.statusMap[cacheKey] = true;
    const result = await this.refresh(params);
    this.complete(result, cacheKey);
    return result;
  },
  // 请求接口
  async refresh(params) {
    const res = await requestUrl(params);
    // TODO 可以对请求结果做处理
    return res;
  },
  // 请求完成后
  complete(result, cacheKey) {
    this.statusMap[cacheKey] = false;
    while (this.queueCallbacks[cacheKey]?.length) {
      const { resolve } = this.queueCallbacks[cacheKey].shift();
      resolve(result);
    }
    this.setCacheData(cacheKey, result)
  },
  // 设置缓存数据
  async setCacheData(cacheKey, val) {
    this.cacheMap[cacheKey] = val;
  },
  // 清除缓存数据
  async clear() {
    this.cacheMap = {};
    this.statusMap = {};
    this.queueCallbacks = {};
  }
};

export default singleManage;