因网络不好导致请求时间太长问题的解决

问题描述:

        项目生产环境,网不太好,后台服务器返回的数据量又太大,请求开始会有一个遮罩,请求结束遮罩才会关闭,因为数据一直在接收中,导致这段时间内什么操作都做不了,只能杀死进程在重新进入。这里需要加一点东西,如果多长时间内数据还没有接收完,结束这个请求

解决过程:

        我知道有的人可能会想,直接在请求多少秒后把遮罩关掉就好了,我也这么想过,但是这样只是关掉了遮罩,而请求依然存在,治标不治本。刚好在在前段时间把vue基础看完,所以这里就想到了请求拦截,axios的。很多时候,如果我们知道bug是在什么样的情况下出现的(场景复现),解决这个bug会相对来说比较容易一些,直接在代码里跟着操作走一遍可能就会发现问题所在,所以我们这里先复现问题并尝试用请求拦截试试。

        之前看vue的视频,刚好自己有用node搭建的简单服务器,这里就直接用这个简单服务器来模拟了。

因网络不好导致请求时间太长问题的解决

        这里可以看到,服务器里就一个简单的接口,返回了点数据,没有其他什么东西了

        axios的拦截分为请求拦截器和响应拦截器,请求拦截器是在向服务器发起请求之前做些什么,响应拦截器是在服务器把响应数据返回之前做些什么,这里先不谈拦截器的应用场景。现在开始给axios请求添加拦截器,在拦截器里把请求所花费的时间打印出来,关键代码如下

因网络不好导致请求时间太长问题的解决

因网络不好导致请求时间太长问题的解决

        这里我们可以看到打印信息,一共只花了0.0029秒,这,后台多发点数据,然后网速换成最慢的再试试,换网速看下图,越往上越慢,这里我们直接换到最慢的再试试

因网络不好导致请求时间太长问题的解决

       4.529秒,问题复现完成,这下我们只要在两秒内把请求结束就可以了,等等,页面刷新再试一次,会发现一个问题,拦截器里打印的请求时间几乎和成功回调里同时出来的,也就意味着在数据全部接收完成之后,你才可以做一些操作,所以响应拦截器是在把数据完全接收后,成功或失败回调之前执行的,好吧,响应拦截器解决不了这个问题,还得找找其他办法。点开请求,看下耗时,这里我们会发现等待时间只有509毫秒,接收数据就用了4秒(说明确实把问题给复现了)。是不是可以在等待之后,加一个延时定时器,多少秒之内取消请求?这里我在往上查了好多资料,包括axios的官方文档,甚至往上去找了promise对象,没有找到需要的。再找找http请求过程、机制,还是没有,当然也可能是我没有找到,如果有知道可以告诉我。

因网络不好导致请求时间太长问题的解决

 

       请求拦截失败了,看来还得找找其他解决思路,如果我们在发起请求之后写一个延时定时器,在多少秒后取消这个请求,是不是就把问题解决了?上代码

因网络不好导致请求时间太长问题的解决

因网络不好导致请求时间太长问题的解决

       这里把延时定时器放在请求后也行,请求拦截器里不行,问题解决了。再看看项目代码,擦哩,这里封装的好像不是axios,封装的是vue-resource,那就再来一份vue-resource的。这里再说个技巧,我们在引用vue-resource、element ui等这些时,可以直接引用CDN链接(https://www.bootcdn.cn/),也可以直接去CDN链接里把代码全部复制下来,在本地新建一个js文件,引入这个js文件(这个不需要网)。vue-resource取消请求查了很多资料,只能取消上一个请求,这里这样稍微改一下就可以取消当前请求了,上代码

因网络不好导致请求时间太长问题的解决

最终版本:

      到这里问题就解决了,因为项目用的是封装好的,旨在最小改动的情况下解决问题(改动越多,出现问题的可能性就越大)。所以这里对代码进行了优化,只改两处,下面是关键代码,第一个是封装的地方,第二个是main.js引入vue-resource的时候添加了一个全局的拦截器

因网络不好导致请求时间太长问题的解决

因网络不好导致请求时间太长问题的解决

      paramData.messageBody是发起post请求传给后台的数据,这样写的好处是,如果需要超时处理的话,你只需要在传给后台的数据里添加一个字段_timeout(单位毫秒),如果这个字段存在的话,就做超时处理,如果不存在,则还是与之前一样。需要说明的地方是,全局拦截处理后,请求会在超时后走到失败回调里,这里我们自定义了一个超时处理状态码和文本,让我们可以知道该请求是因为请求超时而导致的请求失败。