管理网络请求的与缓存请求数据,提高性能

4 篇文章 0 订阅

网络请求的往往是限制前端新能的重要因素,页面的卡顿往往不是前端渲染的问题而是请求数据慢或者频繁请求导致的。大型复杂的业务更加需要做请求的缓存,同时又要有细粒度的控制能力,哪些请求可以缓存,哪些请求不需要缓存,哪些请求可以直接存到localStorage里,哪些只在当前页面做缓存,以及何时应该清理缓存。为了解决以上问题,我们自己封装了一个强大的createService方法,可以高效,便捷,细粒度去控制组件的请求,并且避免相同的请求重复执行,但在做缓存的同时一定要注意是不是真的需要做缓存,数据是否有时效性的要求。

下面直接上代码,沉淀了两年的createService终于出炉了(其中的一些依赖(request,Storage)就不罗列了,理解设计思想就可以),最终目的就是创建一个mixin


export const createService = (defaultOptions = {}) => {
	const {
		key,
		url,
		parser = null,
		cache = false,
		vuex = false,
		param: defaultParam = {},
		getParam = (instance) => ({})
	} = defaultOptions;
	let store;
	cache && (store = Storage.get(`${key}_${_global.version}`));
	store = store || { ...serviceObj };

	// clear, 这块代码只会执行一次,所以退出登录后不应该吧cbs清空
	!cache && serviceManager.add(() => {
		store = { ...serviceObj };
	});
	let loadPromise;

	return {
		[key]: (userOptions = {}) => {
			const options = { ...defaultOptions, ...userOptions };
			// 具体看哪些参数可以被重置的
			const { autoLoad = true } = options;

			// 方法首字母大写
			const strFn = key.charAt(0).toUpperCase() + key.slice(1);

			const loadKey = `load${strFn}`;
			const clearKey = `clear${strFn}`;
			const loadingKey = `loading${strFn}`;

			return {
				data() {
					return {
						[key]: [],
						[loadingKey]: false
					};
				},
				created() {
					autoLoad && (this[loadKey + 'Promise'] = (this[loadKey]({ ...defaultParam, ...getParam(this) })));
				},
				methods: {
					[loadKey](param, opts = {}) { // eslint-disable-line
						this[loadingKey] = true;
						let ajax = vuex ? this.request : this.$request;
						const localData = serviceCompare(param, store);
						const wrapPromise = (p) => {
							return p.then((res) => {
								res.parsedData = res.parsedData || (parser && parser(res.data));
								store = {
									param,
									res,
								};
								this[key] = store.res.parsedData || store.res.data;
								typeof cache === 'function' ? cache(key, store) : cache && Storage.set(`${key}_${_global.version}`, store);

								return res;
							}).catch((res) => {
								console.error(res);
								this.$Message.error(res.msg);
								return Promise.reject(res);
							}).finally(() => {
								this[loadingKey] = false;
							});
						};
						if (!localData && loadPromise && isEqualWith(store.param, param)) {
							return wrapPromise(loadPromise);
						}
						loadPromise = ajax({
							url, // 必须是mutationType
							type: 'GET',
							localData,
							loading: false,
							param,
							...opts
						});
						return wrapPromise(loadPromise);
					},
					[clearKey]() {
						store = { ...serviceObj };
						loadPromise = undefined;
						this[loadingKey] = false;
					}
				}
			};
		}
	};
};

使用方式

定义service(此处的initTree可以看我的另一篇树结构处理的博客,个人觉得还是不错的)

const services = {
	// 手机国际区号
	...createService({
		key: "mobilePrefix",
		cache: true,
		url: '_COMMON_MOBILE_PREFIX_GET',
	}),
	// 全国所有的地址
	...createService({
		key: "region",
		url: '_COMMON_PUBLIC_ALL_GET',
		cache: true,
		parser: (data) => initTree(data, { labelKey: 'region_name', valueKey: 'national_code', childrenKey: 'children' })
			
	}),
	// 物流公司
	...createService({
		key: "logisticsCompany",
		url: '_COMMON_PUBLIC_EXPRESS_ITEMS_GET',
		cache: true
	})
};

调用service

import service from '@stores/services/common';


export default {
	name: 'xls-filter',
	components: {
		
	},
	mixins: [service.region()]
....
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值