ajax请求合并

290 阅读1分钟

cacheApi.js

import api from '@/api/index';
// 用来缓存Promise对象的数组 { key: url+param, value: promise }
let promiseList = [];

// 每隔1分钟清空一下promise列表,防止内存溢出
setInterval(() => {
  promiseList = [];
}, 60000);

// 检查
function checkPromise(url, param) {
  let key = url + JSON.stringify(param);
  // 看看有没有相同 Promise
  let res = promiseList.filter(item => item.key === key);
  // 如果有相同的进行中的promise,直接返回
  if (res.length > 0) {
    return res[0].value;
    // 如果没有相同的则需要存入当前的Promise并返回
  } else {
    return false;
  }
}

// 自己封装的get请求
// 使用的时候多传一个参数merge 表示是否使用并发合并的功能
export default function zGet(url, param, merge = true) {
  // 检查是否命中缓存中的promise如果有返回命中,不再发出请求
  let cachePromise = checkPromise(url, param);
  if (merge && cachePromise) {
    return cachePromise;
  }

  let promise = api.get(url, { params: param });
  promiseList.push({
    key: url + JSON.stringify(param),
    value: promise,
  });
  return promise;
}

请求拦截器


import axios from 'axios';
import qs from 'qs';
import { message } from 'antd';

import URI from 'urijs';
import setting from '@/setting';
import { jsonp } from "@/utils/util";

// import Logger from '@/../libs/Logger';
// const LoggerIns = Logger.Init();

// import logger from '@/../libs/Logger'
const api = axios.create({
	baseURL: setting.baseURL,
	timeout: setting.timeout,
	headers: {
		'x-requested-with': 'XMLHttpRequest'
	}
})

api.interceptors.request.use(conf => {
	if (conf.method === 'post') {
		// 没有显式设置'Content-Type'
		if (!conf.headers['Content-Type']) {
			conf.headers['Content-Type'] = 'application/x-www-form-urlencoded';
			conf.data = qs.stringify(conf.data, { arrayFormat: 'repeat' });
		}
	}
	return conf
}, err => {
	return Promise.reject(err)
});

function sendResponse(res = {}) {
	const {
		config = {},
		data = {},
		method,
	} = res;
	let { code, msg, token } = data;

	
	let destination = '';
	if (`${code}` === '110000') {
		// 未登录,需要登录
		const uri = new URI('http://login.doba.com/');
	
	}
	const redirect = destination ? {
		destination,
	} : -1;
	return {
		...data,
		redirect,
	};
}

api.interceptors.response.use((res, req) => {
	if (!res.data) return null;
  } else {
		return sendResponse(res);
	}
}, err => {
	if (axios.isCancel(err)) {
		console.log('request cancel', err)
	}
	return Promise.resolve({});
})


const serverRequest = (req, fetchFun) => {
	if(!req){
		req = {};
	}
	const config = {};
	if (!!req?.headers) {
		// 服务端请求
		const _headers = req?.headers || {};
		config.baseURL = setting.baseInnerUrl;
		delete _headers['accept'];
		config.headers = {
			..._headers,
			// Cookie: _headers?.cookie || '',
			// 'x-forwarded-for': _headers['x-forwarded-for'] || '',
			referer: _headers?.referer || `http://www.doba.com${req?.url}`, // 主要用于跳转登录页面回跳地址
		}
		if (PROCESS_ENV !== 'development') {
			config.headers.host = 'www.innerdoba.com';
		}
	}
	return async (params = {}) => {
		// 服务端请求,基本为get请求,传参为params
		config.params = params;
		return fetchFun(config);
	};
};

export { api as default, serverRequest }