React 异步请求内存泄漏

1、写在前面

本篇文章旨在解释react异步请求内存泄漏问题的原因,以及对AbortController使用探索,欢迎各位童鞋一起探索交流。
React 异步请求内存泄漏_第1张图片

2、怎么会这样,why((灬ꈍ ꈍ灬))

image.png
经常用react开发项目的小伙伴应该经常碰到这种问题,即一个弹出框或者一个组件被另外一个组件立即销毁,但被销毁或者关闭的弹出框内部可能正在某种请求中(请求表示:这不能怪我啊,我还没回城呢,你却拆了我家,嘤嘤嘤~~),这时销毁了组件,但请求还在路上,请求的回调还没释放,这就导致了内存泄漏。

3、AbortController

咋个办呢,用一个变量存贮是否即将销毁?willUnmount时setState为true?为true时做一些操作?。。。
貌似不怎么行呀,已经在途中的请求怎么召回?class组件可以使用生命钩子,但hooks呢,没有钩子,Fetch,axios好像也都只返回promise,当然rxjs可以(subscribe返回句柄,可以在effect下return unsubscribe),但rxjs团队学习成本比较高,比较少用。怎么办呢?
AbortController对象实现了可以与请求通信的接口,通过它我们可以显示的中止请求。

属性:AbortController.signal 一个AbortSignal对象,我们可以拿着它与request对话或者中止它
Returns an AbortSignal object instance, which can be used to communicate with, or to abort, a DOM request.

方法:AbortController.abort 在一个请求完成前中止它
Aborts a DOM request before it has completed. This is able to abort fetch requests, consumption of any response bodies, and streams.

使用(how to use)

React 异步请求内存泄漏_第2张图片

React 异步请求内存泄漏_第3张图片
Wow, It's seem Ok!
好像可以了,销毁了请求也被中止了,回调更改react状态也中止,不错。

但是大家不知发现什么问题没有,每一个请求都如此处理是否太麻烦?一个AbortController的signal是否能控制多个请求,还是像promise一样状态凝固?
所以,让我们来测试一下
React 异步请求内存泄漏_第4张图片
测试结果:AbortConntroller的abort存在和promise一样的问题,一旦状态凝固,再使用这个实例signal的请求将直接拒绝

优化

大家使用react开发项目,肯定就是工程化项目,不止一个地方使用请求,一个个去写逻辑肯定不现实,但设计AbortController的单例模式显然不合适。在那axios封装request方法的时候用工厂模式生成AbortController,并在返回的promise上增加属性,让使用者拿到控制器。

你可能感兴趣的:(React 异步请求内存泄漏)