最近赶项目,一周上7天班每天还得搞到十点十一点,实在是没有精力再看书了。
但是写项目的时候碰到的一个Bug完全超出了我的知识范围,我隐隐感觉如果解决了应该会让我对JS有更好的认识,于是没有求助大佬,恳求给我些时间来解决。大佬正忙着也不想弄什么疑难杂症于是同意了。我可得好好看看这玩意什么毛病再写个博客记一记了........
Bug是这样的:
做了一个选择本月、本年、全部的部分,但是很奇怪,调的都是同样一个函数只是传参不同,点击本月、本年后可以正常的把展示的样式改为点击后的 ,但是全部却点击不上。
可以看到,我是用dateBtnChoose这个变量来进行选择判断的。二话不说先Console。
先在本月后面加了dateBtnChoose的调用,然后再在调用的函数里写了console.奇怪的事情发生了。
发生了我根本无法理解的事情,同样一个函数传参,同样的显示,参数是1、2时正常,但是参数为3的时候可以确定type=3,dateBtnChoose同样等于3,但是dateBtnChoose显示出来居然是0?排查之后发现,也没有对dateBtnChoose=3进行判断的部分,也就是说根本不是代码里进行操作导致的Bug.
开始头疼了。排查了半天无果,向大佬求助,大佬看了一下给了提示:“双向绑定”。
于是开始思考。已知这些值是双向绑定的....有什么问题吗?苦苦思索,有哪里把dateBtnChoose置0了吗?找了一遍,发现日期input框中@change绑定的@dateSelectClear只有一行:
this.dateBtnChoose= 0;
于是尝试删除@change,发现问题没有了。但需求是,如果我手动在UI的日期框输入了日期,那么按钮选择置0,这个@change不能随便删除。再仔细想想,我大概明白是怎么一回事了。
在点击button后,调用了函数selectsearchDate(type),此时将this.dateBtnChoose的值置为type.但是selectsearchDate这个函数同样操作了绑定在el-date-picker上的this.searchParamsObj,这个操作会引起el-date-picked的改变,继而触发@change,然后触发函数dateSelectClear,将this.dateBtnChoose置0.
那么怎么解决呢?想了半天,有点束手无策。问大佬,大佬提示:“你傻吗,加个读写开关不就行了。”
大概明白怎么做了。加入一个读写开关值isBtnStatus,在值change的时候做读写保护。
使用值isBtnStatus:
只有当isBtnStatus不为1时,才在触发@change的时候将dataBtnChoose置为0,并在触发@change后将isBtnStatus置为0.
在selectsearchDate中加入对isBtnStatus值的操作。赋值之后,将isBtnStatus置0。因为!this.isBtnStatus的值为0,接下来对startdate和enddate的操作并不会触发@change中的置0,而在对startdate和enddate进行操作、触发@change后,重新将isBtnStatus置0.此时的@change再进行触发,即可为正常值。
但是,又发现了一个新的问题,那就是点击多次以后偶尔会出现点击日期框后按钮样式并未转变的问题。
点击多次以后会出现偶尔有一次,点击一个按钮后,通过更改日期值并没有办法将按钮值清零。出现频率大概是点击7-8次出现一次。这下我就确实有些不知如何是好了,于是无奈又只能请教大佬。
大佬看了以后陷入了沉思。语重心长的给了我提示:“这么明显的异步请求问题都看不出来?执行完选择后加个setTimeout不就好了吗?是不是傻?”
我感觉大佬说的很对。searchByType()函数调用了接口,js进行异步执行,此时会出现接口还在调取中,
this.searchParamsObj.StartTime=startdate;
this.searchParamsObj.EndTime=enddate;
这两句还没有执行完,就直接执行
this.isBtnStatus = 0;
然后接口又调到数据了,触发@change,血崩,功能失效。
于是我把函数改成:
终于没有问题了,感动。
这次的Bug还是让我感到有点惭愧的,这么多基础知识居然理解的这么浅薄,碰到实际问题就蠢的找不着北,真鸡儿丢人......
默默刷Vue官方文档去了....