一、封装缓存

preventRequest.js

import Qs from 'qs';

class preventRequest {
  constructor(options) {
    const { maxNum, expiredTime } = options || {};

    // 请求队列
    this.list = [];
    this.MAX_NUM = maxNum || 100;
    this.EXPIRED_TIME = expiredTime || 60000;
  }

  getRequestKey(config) {
    const { method, url, params, data } = config;
    return [method, url, Qs.stringify(params), Qs.stringify(data)].join('&');
  }

  add({ config, data }) {
    if (config.data) config.data = JSON.parse(config.data);
    let key = this.getRequestKey(config);
    let index = this.list.findIndex((t) => t.key === key);
    if (index > -1) {
      this.list[index].data = data;
      this.list[index].resolve(data);
    } else {
      // 添加到缓存列表中
      this.list.push({ time: Date.now(), key, data });
    }
  }

  find(config) {
    let key = this.getRequestKey(config);
    let index = this.list.findIndex((t) => t.key === key);
    if (index > -1) {
      let item = this.list[index];

      // 判断是否超出了最大缓存时间
      if (Date.now() - item.time > this.EXPIRED_TIME) {
        // 清除该缓存
        this.list.splice(index, 1);
        return undefined;
      } else {
        return item;
      }
    }

    // 添加缓存信息
    let newItem = { key, time: Date.now() };
    newItem.data = new Promise((resolve) => {
      newItem.resolve = resolve;
    });

    // 判断是否超出了最大缓存数量
    if (this.list.length === this.MAX_NUM) {
      this.list.shift();
    }
    this.list.push(newItem);

    return undefined;
  }
}

const RequestCache = new preventRequest();
export default RequestCache;

二、改造Axios实例

httpRequest.js

import axios from 'axios';
import RequestCache from './preventRequest.js';

const serverURL = "xxxx"
const service = axios.create({
  baseURL: serverURL,
  responseType: 'json',
  timeout: 60000,
  headers: {
    'Content-Type': 'application/json'
  }
});

// request拦截器
service.interceptors.request.use(
  (config) => {
    // ... do something

    const isCache = RequestCache.find(config);
    if (isCache) {
      config.adapter = function (config) {
        return new Promise((resolve) => {
          const res = {
            status: 200,
            statusText: 'OK',
            headers: { 'content-type': 'application/json; charset=utf-8' },
            config,
            request: {}
          };

          if (isCache.data instanceof Promise) {
            isCache.data.then((data) => {
              resolve({ ...res, data });
            });
          } else {
            resolve({ ...res, data: isCache.data });
          }
        });
      };
    }

    return config;
  },
  (error) => {
    Promise.reject(error);
  }
);

// respone拦截器
service.interceptors.response.use(
  (res) => {
    // ... do something

    RequestCache.add(res)
    return response;
  },
  (error) => {
    Toast({
      message: '网络异常,请稍后再试',
      position: 'bottom'
    });
  }
);

export default service;
文章目录