前端性能优化:实现请求中断以节约网络资源

实现当上一个请求未完成时进行重复请求则取消上一个请求,以及当路由跳转时取消前一个路由中未完成的请求

实现思路

将每一个请求的取消函数保存起来,当请求正常结束时,将保存的取消函数清除,当重复进行相同请求时,调用上一个请求的取消函数,并用新请求的取消函数进行覆盖,监听路由变化,当路由跳转时,调用其它路由中请求的取消函数

实现方法

  1. 使用一个map来保存,key和value分别是每个请求的标识和请求对应的取消函数
export const CacheUtil: {
	cache: { [key: string]: any },
	clearCache: (key: string) => void,
	clearOther: (key: string) => void,
} = {
	// 映射关系
	cache: {},

	// 根据提供的键名取消对应的请求
	clearCache(key: string) {
		if (key) {
			const cancle = this.cache[key]
			if (cancle && typeof cancle === 'function') {
				cancle()
				delete this.cache[key]
			}
		}
	},

	// 根据提供的页面路径取消其它路径的请求
	clearOther(herf: string) {
		if (herf) {
			Object.entries(this.cache).forEach(([key, cancle]) => {
				if (key.split("__")[1] !== herf) {
					cancle()
					delete this.cache[key]
				}
			})
		}
	}
}
  1. 存入缓存和删除缓存的时机分别是请求开始之前和请求结束之后,对应axios的拦截器。这里使用axios的cancleToken来拿到每个请求的取消函数:
// 在请求拦截器中
this.instance.interceptors.request.use(
	(config) => {
		// 拼接method、请求url以及路径名来保证一个cacheKey表示一个请求
		let cacheKey = config.method + '_' + config.url + '__' + history.location.pathname

		if (cacheKey) {
			// 将上一个未完成的相同的请求中断
			CacheUtil.cache[cacheKey] && CacheUtil.clearCache(cacheKey)

			// 将当前请求对应的取消函数存入缓存中
			config.cancelToken = new axios.CancelToken((c) => {
				if (cacheKey) CacheUtil.cache[cacheKey] = c
			})
			
			// 将cacheKey保存在config中,以便在相应拦截器中通过cacheKey将缓存释放
			config.cacheKey = cacheKey
		}
		return config
	},
	(error: any) => {

		return Promise.reject(error)
	}
)

// 在响应拦截器中
this.instance.interceptors.response.use(
	(response) => {
		// 请求正常完成,将缓存释放,下面请求错误时也一样
		const cacheKey = response.config.cacheKey
		cacheKey && delete CacheUtil.cache[cacheKey]

		return response
	},
	(error: any) => {
		if (error.config) {
			const cacheKey = error.config.cacheKey
			cacheKey && delete CacheUtil.cache[cacheKey]
		}

		return Promise.reject(error)
	}
)
  1. 使用umi3.x的history.listen进行路由监听,当路由变化时调用CacheUtil.clearOther
import React, { useEffect } from 'react'
import { history } from 'umi'
import { CacheUtil } from '@/utils/CacheUtil'

const Page = () => {

	useEffect(() => {
		const unlisten = history.listen((location, action) => {
			CacheUtil.clearOther(location.pathname)
		})

		return () => {
			unlisten()
		}
	}, [history])
	
	return (<div>Page</div>)
}

export default Page
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值