My Little World

多请求loading处理

背景

项目中所有http请求走同一个全局公共函数,函数参数为:请求方法,url, 请求参数,回调函数以及是否需要加loading的一个布尔值

一般情况下都需要加loading,所以第5个参数一般不填,默认为true,需要加loading
不加loading的情况也有,例如下载一个文件的过程,如果是由前端来组装文件流,这个时候是不加loading的

loading效果的添加是通过jquery判断有没有loading效果对应的DOM,有的话就先remove再append
loading效果的消失通过jquery remove掉相关DOM元素

即在全局公共函数发出http请求前,根据第5个参数,添加loading,请求结束后取消loading

问题

一个配置页面,跳转过来时需要加载多项数据进行初始化,而且数据之间有一定关联
比如,异步请求A,B,C,D四个数据,请求完D之后,在回调函数中,需要根据D数据发出请求E,再根据E返回数据请求F
导致的现象是,ABCD数据回来比较快,然后loading消失,发出E时loading重现,消失和重现时间距离较短,
造成页面闪烁

目标

加载ABCDEF请求loading仅显示一次,消失一次

分析

1.其实本身发出ABCD四个异步请求时也会发生loading问题,即,如果A请求回来的比其他三个早很多,loading会提前结束
2.从D返回的数据可能为空这时就不需要去请求E,F请求也就不用发出,同样如果E没数据,也就不要请求F,这时候loading在哪结束需要判断

解决

1.在加载loading和消失loading时,添加一层计数,加载loading,计数count加1,消失loading计数count减1,当count减为0时,loading再消失
这样就可以解决异步请求loading提前消失
2.D请求完才会发出E请求,这时如果ABC请求早已结束,count已经被减为0 ,会重新开始计数,loading会重现造成闪烁,还是不能解决直接问题,
解决办法就是,在请求回来时,利用settimeout包裹计数减1,loading消失过程,先执行回调函数再减1,
这样,如果D有数据,count会因为要发请求E先加1,然后执行settimeout减1,这样loading就不会因为减到1而消失
如果 D没数据不发出请求E,同步执行完回调函数后,执行settimeout减1,count减到0,loading消失

后续

回调函数中,有同事代码编写存在BUG,比如没有判断对象是否存在直接去使用其身上的属性值,这样的error会在请求的catch中被捕捉到,
因为请求发生错误,状态码非200都会被捕捉到catch中,这时也需要将loading关闭,
这样就会造成在回调函数发生错误时,count被减了两次,第一次是请求正常回来时,第二次是回调函数发生错误在catch中被减1,
这样count就被减成了小于0,之前的判断以及count等于0,loading消失不再适用,
因此将判断界限定为小于1即loading消失,进行容错处理