DEV Community

Leo
Leo

Posted on • Edited on

自定义请求共享函数:避免重复请求的优雅方案

在日常前端开发中,我们常常会遇到这样的场景:

某个接口被多个组件或多次触发调用,而它们本质上请求的是同一个数据,如果不做处理,就会导致接口重复请求,浪费性能。

本篇文章封装一个「请求共享函数」,让同一个请求在未完成时被多个地方共享,只发一次请求,大大提升效率和用户体验。

问题场景

举个例子:

// 调用两次同一个接口
getUserInfo().then(...)
getUserInfo().then(...)
Enter fullscreen mode Exit fullscreen mode

如果不做处理,会发出 两次请求,甚至在组件或页面频繁切换时,可能会发出 三四次相同请求,不仅浪费性能,还可能带来副作用(如状态不一致、闪屏等问题)。

解决思路

封装一个函数:当某个请求正在进行中时,后续请求使用缓存中的 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

}
Enter fullscreen mode Exit fullscreen mode

使用示例

假设你有一个封装好的 request 请求方法,可以这么使用:

import { sharedRequest } from './utils/shared-request'
import { request } from './utils/request'

function getUserInfo() {

  return sharedRequest('get-user-info', () =>
    request('/api/user')
  )

}
Enter fullscreen mode Exit fullscreen mode

即使你在多个地方同时调用它:

getUserInfo().then(data => console.log('A', data))
getUserInfo().then(data => console.log('B', data))
Enter fullscreen mode Exit fullscreen mode

控制台只会打印一次接口请求,返回数据会被复用给多个调用方。

适用于:

  • 用户详情
  • 配置项列表
  • 权限信息
  • 公共资源加载等

总结

  • 避免重复请求
  • 减少接口压力
  • 提高用户体验
  • 保持代码整洁

Top comments (0)