18

源代码

import axios from 'axios'

// 数据存储
export const cache = {
  data: {},
  set (key, data) {
    this.data[key] = data
  },
  get (key) {
    return this.data[key]
  },
  clear (key) {
    delete this.data[key]
  }
}

// 建立唯一的key值
export const buildUniqueUrl = (url, method, params = {}, data = {}) => {
  const paramStr = (obj) => {
    if (toString.call(obj) === '[object Object]') {
      return JSON.stringify(Object.keys(obj).sort().reduce((result, key) => {
        result[key] = obj[key]
        return result
      }, {}))
    } else {
      return JSON.stringify(obj)
    }
  }
  url += `?${paramStr(params)}&${paramStr(data)}&${method}`
  return url
}

// 防止重复请求
export default (options = {}) => async config => {
  const defaultOptions = {
    time: 0, // 设置为0,不清除缓存
    ...options
  }
  const index = buildUniqueUrl(config.url,config.method,config.params,config.data)
  let responsePromise = cache.get(index)
  if (!responsePromise) {
    responsePromise = (async () => {
      try {
        const response = await axios.defaults.adapter(config)
        return Promise.resolve(response)
      } catch (reason) {
        cache.clear(index)
        return Promise.reject(reason)
      }
    })()
    cache.set(index, responsePromise)
    if (defaultOptions.time !== 0) {
      setTimeout(() => {
        cache.clear(index)
      }, defaultOptions.time)
    }
  }
  return responsePromise.then(data => JSON.parse(JSON.stringify(data))) // 为防止数据源污染
}

例子

例如

import axios from 'axios'
import cache from './cache'
 
// get请求
export async function getData (payload) {
  return axios.get('/path', {
    params: payload,
    adapter: cache({
      time: 0
    })
  })
}

// post请求
export async function postData (payload) {
  return axios.post('/path', payload, {
    adapter: cache({
      time: 1000
    })
  })
}

API

time 表示可缓存的时间,默认为0,在没有清除内存之前永久缓存(浏览器窗口标签关闭,应用程序关闭等会清除内存)

防止重复提交

time 设置一个极短的时间,比如1000,就表示在1000毫秒之内不会重复向服务器发出请求,当然你也可以用new CancelToken,但会导致本次请求报错,需要做异常处理


zhaowenyin
369 声望22 粉丝

我会修电脑