全局 message 去重复的思路
ericwxy

问题是什么

在我们日常的前端开发过程中会遇到这么一个问题,就是我们在进入页面的时候通过Promise.all() 或者通过其他方法发起多个网络请求,在这些请求由于网络原因报错的时候页面上方会飘下来一串一摸一样的 错误消息提示。或者在图片上传的时候我们同时上传很多张图片而且上传速度都差不多,也会像上面那种情景一样从页面上飘出一串“上传成功”之类的消息。

虽然这没有影响到页面的功能,但是作为有追求的开发者总会觉得不够“极致”。而却这样也会徒增一些页面渲染的压力(我们都知道 DOM 操作是“昂贵”的)。

最初的解决方案

我们知道了”是什么“,那么接下来我们改如何优雅的解决这个问题呢?

我一开始遇到这个问题是在一个 PC 的项目开发中,就是会在多个网络请求失败的时候。由于一般情况下这种网络请求的错误提示都是全局写在 axios 拦截器里面的,我们只需要在拦截器抛出错误消息的地方”套“一层就可以解决了。关键是怎么”套“。

image

以上是我最初在 PC 项目中的解决方案。

思路主要是以下几个点

  • 封装一个 高阶函数(HOF) ,返回的方法在 axios 的错误拦截器中使用。
  • 内部利用闭包维护一个 消息队列(msgQueue)以及队列的一系列操作。
  • 在消息入队列的的方法里做一个去重复的判断。
  • ”清空消息队列“ 的操作做一个简单的“防抖” ,在短时间内不再有新的消息进入队列则会清空/展示队列中的消息。

可是随着开发需求的不断变化,我发现这种方案可能存在一定的隐患。如果我们光在 http 请求这部分用还好,可是需要去重复的全局消息应该不止有 http 请求错误吧。那么一旦引用这个方法的地方多了,就会独立存在很多个”消息队列“在内存中(闭包)造成不必要的”资源浪费”。

更优的解决方案

于是就有了下面这个方案。

image

上面这个方案与第一个方案都是基于“队列”的思路来解决问题,不同点在于它用了单例模式来解决多出引用开辟独立空间的问题。全局的消息队列都是单例中的 msgQueue。

写在最后

个人觉得这个例子还是有很多点值得“盘”的,如 队列数据结构、高阶函数、闭包、单例设计模式… 日后我也会在日常的开发中多将学到的知识应用在代码里并多多记录的。


(来自 2024 的自己:在”华子”工作的时候项目里的组件库有一个思路可以借鉴,就是加上 key ,和一个布尔值的字段用来控制是否去重,判断依据为前面的唯一的 key)

 评论
评论插件加载失败
正在加载评论插件