在日常前端开发中,我们常常会遇到这样的场景:
某个接口被多个组件或多次触发调用,而它们本质上请求的是同一个数据,如果不做处理,就会导致接口重复请求,浪费性能。
本篇文章封装一个「请求共享函数」,让同一个请求在未完成时被多个地方共享,只发一次请求,大大提升效率和用户体验。
问题场景
举个例子:
// 调用两次同一个接口
getUserInfo().then(...)
getUserInfo().then(...)
如果不做处理,会发出 两次请求,甚至在组件或页面频繁切换时,可能会发出 三四次相同请求,不仅浪费性能,还可能带来副作用(如状态不一致、闪屏等问题)。
解决思路
封装一个函数:当某个请求正在进行中时,后续请求使用缓存中的 Promise,直到请求完成后清除缓存。
关键点是:
- 缓存正在执行的 Promise
- 请求完成后自动清除缓存
- key 用于唯一标识一个请求
实现代码:sharedRequest
// utils/shared-request.js
const requestCache = new Map()
/**
* 请求共享函数:确保同一个请求只发起一次
* @param {string} key 唯一标识每个请求
* @param {() => Promise<any>} requestFn 返回 Promise 的请求函数
* @returns {Promise<any>} 请求结果
*/
export function sharedRequest(key, requestFn) {
if (requestCache.has(key)) {
return requestCache.get(key) // 返回已有的请求
}
const promise = requestFn()
.finally(() => {
requestCache.delete(key) // 请求结束,清除缓存
})
requestCache.set(key, promise)
return promise
}
使用示例
假设你有一个封装好的 request 请求方法,可以这么使用:
import { sharedRequest } from './utils/shared-request'
import { request } from './utils/request'
function getUserInfo() {
return sharedRequest('get-user-info', () =>
request('/api/user')
)
}
即使你在多个地方同时调用它:
getUserInfo().then(data => console.log('A', data))
getUserInfo().then(data => console.log('B', data))
控制台只会打印一次接口请求,返回数据会被复用给多个调用方。
适用于:
- 用户详情
- 配置项列表
- 权限信息
- 公共资源加载等
总结
- 避免重复请求
- 减少接口压力
- 提高用户体验
- 保持代码整洁
Top comments (0)