阅读 14438

你还在为项目里的重复请求发愁吗?

github blog: github.com/SugarTurboS…

前言

最近发现项目里面会出现一些重复的请求,在某些页面中,相同参数相同地址的请求会在1s之内连续发送多次。为了解决这个问题,最终做出了两个工具(repeat-request-minderrepeat-request-minder-webpack-plugin)来辅助我们避免重复的请求。

背景

随着项目越来越复杂,写代码的时候难免会没留意到有些请求在别的组件已经发送过,特别是用了 hooks 之后,有一些 hook 在 useEffect 中封装了请求的逻辑,而hook被多个组件引用导致重复请求。另外也有可能是按钮的点击没有防抖造成重复发送请求。 通常面对这些状况,我们都只能是在控制台上人为的检查,比较难发现并处理。

重复请求的危害

这些重复的请求主要有两个影响

  • 增加服务器的压力
  • 可能由于其中的某个请求失败导致页面显示错误

解决思路

前置处理

一般开发的时候可能不会留意到有重复的请求,要避免这种情况需要自动监控并给出警告,才能从源头杜绝重复请求的发生。

后置处理

出现了重复请求之后能够自动取最后的请求,不发出之前的请求。

结论

但是由于出现问题的原因各不相同,因为我们不应该自动帮开发者把问题掩盖,而是应该将问题暴露出来让开发者自行修复。因此决定做一个可以在开发过程中,自动监控http请求,当出现重复请求的时候能够给出提示的工具。

实现方式

可以通过改写XMLHttpRequest中的方法来实现监控每个请求是否重复,判断方法为:记录接口请求的地址、参数和请求时间在一个对象中,判断当前请求是否1s内连续发送,再判断参数是否相同,如果满足条件则toast提示并将提示打印在控制台。

优化

由于使用了一个对象来缓存每个请求的地址参数和时间戳,那就有可能由于请求非常多而导致这个对象占用的内存过大。
为了控制内存,引入了 LRU Cache 算法来控制缓存的大小。目前设置了缓存请求的数量最大为30个,当有新的请求的时候,会先删掉不经常用的缓存,保证缓存的数量不超过30个。此算法主要使用了一个map对象和一个双向链表来实现,保证新增和插入的时间复杂度为o(1)。

效果

toast提示 控制台输出

repeat-request-minder介绍

repeat-request-minder就是封装了上述功能的一个npm包,使用起来很简单

npm i --save-dev repeat-request-minder
复制代码
import repeatRequestMinder from 'repeat-request-minder';
repeatRequestMinder();
复制代码

调用后就可以自动监控项目中是否有重复的请求,并给出提示了。不设置的话默认会显示toast提示,显示时长为3秒。

repeatRequestMinder({
  isShowToast: true,
  toastTime: 10000
});
复制代码

也可以传入isShowToast和toastTime来控制是否显示toast提示以及提示显示的时长。

repeat-request-minder-webpack-plugin介绍

由于上面说到的包需要在代码中调用,然而我们有时候可能不想这个功能对于业务有侵入性。
于是基于repeat-request-minder做了一个webpack插件,此插件的作用就是在代码打包好了之后,给入口代码插入一段立即执行函数,调用repeat-request-minder的代码。
用这个webpack插件的话,我们就仅需要在webpack的开发配置中引入这个插件,就可以实现在开发过程中监控重复请求并给开发者提示了。 使用方法如下:

npm i --save-dev repeat-request-minder-webpack-plugin
复制代码
const RepeatRequestMinderWebpackPlugin = require('repeat-request-minder-webpack-plugin');
new RepeatRequestMinderWebpackPlugin({
  chunk: 'index',
}),
复制代码

其中的chunk参数为webpack中entry的名字,填上你希望插入此功能的entry名即可。

new RepeatRequestMinderWebpackPlugin({
  chunk: 'index',
  isShowToast: true,
  toastTime: 10000
}),
复制代码

另外同样可以传入isShowToast和toastTime来控制是否显示toast提示以及提示显示的时长。

Github地址

repeat-request-minder
repeat-request-minder-webpack-plugin
觉得有用的话可以点个star✨支持一下