实现多次重复请求接口优化

实现重复请求接口优化

原因

在项目公共组件封装中遇到了这个问题,原因是在这个公共组件中onMounted()调用了一个接口,如果这个组件在其他地方复用就会调一次方法,刚开始没注意这个问题,直到一个页面多次用到这个组件了,一打开这个页面三四个同样的接口!后端小伙伴坐不住了,优化!优化!

过程

一开始想不在onMounted()里调用了,触发事件再调用接口,这样什么时候触发就什么时候调接口获取数据得了,但是很快就pass了,这次出现了一个问题,有延迟,触发事件后,还是需要等待一下,产品那边过不了关。所以最好的方法还是在加载页面的时候就直接把数据加载出来,这怎么处理呢?

突然想到了之前常见的解决多次请求的案例:防抖和节流

茅厕顿开!虽然实际情况不同,但是逻辑有些相似,直接上代码

额外创建getData.ts文件(这里技术栈采用的vue3+ts),

javascript 复制代码
let data = [] as Record<string, any>;
let count = 0;
//用来实现延迟效果
async function delay(ms = 200) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}
export async function useGetData() {
  // 调用接口,获取数据
  const getApiData = async () => {
    const result = await api();
    data = [result?.data];
  };
  //如果判断数据存在直接返回
  if (data && data?.length > 0) {
    return { data };
  }
  if (count++) {
    // 如果有计数说明自己不是第 1 个,就等待
    while (!data || data?.length === 0) {
      await delay();
    }
  } else {
    // 是第 1 个就去请求
    await getApiData();
  }
  count--;
  return { data };
}

这段代码实现的效果就是当短时间内调用时,只会调用一次接口。

整体逻辑就是第一次调用时,count为0,count加1,执行else里的内容,就会执行getApiData()方法,但是加入了await,这样就会等待接口完成后再执行下一步。

而再第二次调用这个方法时,count已经为1,这个时候if判断成功,进入while进行delay()等待,这个时候其实涉及到事件的循环机制了,微任务执行完毕后才能执行下一个微任务,await getApiData()就是一个异步操作,await后面的函数执行完毕时,await会产生一个微任务,加入队列,await delay()也是。所以当数据获取成功后,执行delay()然后跳出while循环,然后最后return {data},其实最终目的都是return {data}。

后面如何再次获取数据时,这个时候也不用经过再判断count了,直接根据之前已经存在过的数据进行返回。

总结

其实总的逻辑还是判断上一次有没有数据,但是加入了接口之后,为了避免请求数据延迟问题,利用事件循环机制的原理进行了一定的处理。

相关推荐
悠悠:)22 分钟前
前端 动图方案
前端
星陈~30 分钟前
检测electron打包文件 app.asar
前端·vue.js·electron
Aatroox34 分钟前
基于 Nuxt3 + Obsidian 搭建个人博客
前端·node.js
每天都要进步哦43 分钟前
Node.js中的fs模块:文件与目录操作(写入、读取、复制、移动、删除、重命名等)
前端·javascript·node.js
brzhang2 小时前
开源了一个 Super Copy Coder ,0 成本实现视觉搞转提示词,效率炸裂
前端·人工智能
diaobusi-882 小时前
HTML5-标签
前端·html·html5
我命由我123452 小时前
CesiumJS 案例 P34:场景视图(3D 视图、2D 视图)
前端·javascript·3d·前端框架·html·html5·js
就是蠢啊2 小时前
封装/前线修饰符/Idea项目结构/package/impore
java·服务器·前端
GISer_Jing3 小时前
React中 Reconciliation算法详解
前端·算法·react.js
呵呵哒( ̄▽ ̄)"3 小时前
react-quill 富文本组件编写和应用
前端·javascript·react.js