【Web前端问题】实在是找不出问题在哪了,麻烦大家找找BUG出在哪
在表单验证的时候出现了如下问题:
我找到了一个办法可以解决这个问题:
将isValid的声明调到上一层作用域中,问题得到解决(这个解决办法给我的启示是好像trigger执行完毕后,isValid又被声明了一次一样,但是我调试发现重头到尾只声明了一次)
另外,只有当第一次验证失败后(即表单的输入不合法),改正表单内的值使其合法后进行第二次验证才会出现这个问题,如果是第一次就输入合法,我调试发现修改isValid的值是始终有效的。
还有,不仅是isValid,我还测试了多个变量声明在enSureCallback函数内,然后在submitHandler中修改,都是和这个一样的情况。
我已经排除了异步的情况,重复声明或者调用的情况,实在是找不出哪里有问题了。因为复现有点麻烦,依赖也有2,3个,所以在线DEMO不好编写。因此大家有任何的猜测都可以提出来,说不定都是解决问题的突破口,先表示一下感谢^_^
----------------------------------------------------2016.10.4补充----------------------------------------------
这是第一次表单输入的值就合法时的函数调用情况
这是第一次表单输入不合法,然后再输入合法时的函数调用情况
可以看到完全没有区别(包括右边调用函数的具体行数),但是BUG就是发生了。。
下面是第一次表单输入的值就合法时的详细情况,当执行了isValid = true这条语句后,我们在call stack中跳转到ensureCallback函数,可以看到值修改是成功的。
下面是第一次表单输入不合法,然后再输入合法时的详细情况,当执行了isValid = true这条语句后,我们在call stack中跳转到ensureCallback函数,可以看到值修改是不成功的。
还有虽然之前已经说了排除了异步的干扰,看到评论里有朋友还是在说这个问题,这里再说明一下,这里真的真的没有异步,是先执行的handler,再return的,而且我调试的时候开了,也没有发现任何异步函数在执行,所以真的可以排除异步的问题了。
现在我的重点思考在于1.为什么只有在第一次失败后才会出现这个BUG,第一次的验证对后面的验证到底产生了什么影响(我是真的想不出有什么影响。。)2.像我之前提到的,为什么将isValid的声明放到上一层作用域去声明就没有BUG了.
希望这次的补充能够帮助大家分析问题
回答:
---------------------------------找到答案了,来结贴了-----------------------------------------
请教了一位朋友,指出了问题所在。主要还是JQ-validate的问题,如下图:
知道了哪里的问题,我们就知道怎么去修复了。即只需要让他的if判断一直为false,并且每次执行都释放之前绑定的事件就行了。为了以后方便维护,我们采取不改validate源码的方式,在进行validate前添加
$formWrap.data('validator')&& ($formWrap.data('validator', null), $formWrap.off());
OK,BUG离我们远去了(但其实这种改法也并不好,因为.off要执行的操作太多了,不过以后肯定是会自己去实现一个validate库的,所以这里就不过于纠结了)。
此外,我们可以编写如下的测试用例用来重现这一问题,如下所示:
function ensureCallback() {
var num = 2;
var o = {
validate:function() {
// 第一次验证的时候我们绑定事件,以后的验证则不再绑定,正是这一点导致了bug
if($('body').data('validator'))
return;
$('body').on('submit', this.submitHandler).data('validator', 1);
},
submitHandler:function(){
console.log('在submitHandler内未修改num时num的值:', num);
num++;
console.log('在submitHandler内修改num后num的值:', num);
}
};
o.validate();
$('body').trigger('submit');
console.log('执行完ensureCallback后num的值为:%d\n\n', num);
}
// 下面我们来模拟那个BUG,即接连两次调用
// 第一次调用模拟的是输入不合法的情况,注意第一次调用会绑定事件
ensureCallback();
// 第二次调用模拟的是输入合法的情况,注意第二次调用不会绑定事件,所以这里trigger后执行的是第一次绑定的
// 事件,所以无论再执行多少次,他都是改变的第一次绑定的事件里面对应的num,对自己的num是没有影响的
ensureCallback();
// 我们甚至可以多调用几次来印证这一点
ensureCallback();
ensureCallback();
ensureCallback();
// 其实这个和输入合法不合法并没有太大关系了,主要是事件的问题
运行结果如下:
如果你还觉得不够清晰,那么可以看下面这张按照顺序结构平铺出来的代码(这张图由那位朋友提供):
这也就很好的解释了为什么将isValid提示一个作用域声明就不会出现BUG,因为那样就能保证无论事件绑定了几次,触发的是第几次,修改的isValid始终为一个值
结语:尽管在这个BUG消耗了很多时间,不过也算是应交的学费了,借助这个问题,也更加了解了事件与闭包,以及在编写插件时应考虑到的问题,也算是小有收获了^_^
回答:
把isValid变量,改为最外层的全局变量试试看。
回答:
将isValid的声明调到上一层作用域中,问题得到解决(这个解决办法给我的启示是好像trigger执行完毕后,isValid又被声明了一次一样,但是我调试发现重头到尾只声明了一次)
我觉得很有可能是被重复声明,可是我又调试不了。你的两个值出现的地方也不一样。
trigger('submit')做了什么?有可能是这步改变了变量。
在var isValid 那儿打个断点试试呢
bug嘛,慢慢调,我喜欢调bug,要是能一起调就好了,不过可以慢慢讨论,一步一步解决,我也想学习。
如果你调好了就OK了
回答:
楼主你这个应该是异步的问题吧,return isValid;
始终返回的是初始值false,因为事件回调函数submitHandler
中修改isValid的值那都是之后的事了,和return isValid;
无关了,因为return isValid;
是在主线程执行的,事件回调函数submitHandler
必须等主线程执行完才会被提取调用
以上是 【Web前端问题】实在是找不出问题在哪了,麻烦大家找找BUG出在哪 的全部内容, 来源链接: utcz.com/a/142778.html