![](/img/trans.png)
[英]Why isn't my if statement executing correctly even though condition has been met?
[英]Having my else statement executed even if condition isn't met in jQuery
好吧,我的标题不可能是真的,因为编程语言不会犯这样的错误,但是这种情况正在发生。 因此,我们可以肯定地说我的逻辑存在问题。
我有一段jQuery / JS代码,就像在AJAX调用之前在SO的注释部分中检查这里要去的字符数一样。 因此,代码被认为是这样的:
如果输入的字符数少于N,则将N个字符减计数(例如,要走2个字符,要走1个字符...)
否则进行AJAX调用,并在成功时显示结果。
当您第一次进入表单时,此过程很顺利:
但是,当我继续使用退格键删除字符(或删除)并再次进入断点(必须看到“ N走”)时,我再次显示了“ N走”部分,但是AJAX调用通过了即使包裹在else
也是else
! 这很奇怪。 结果看起来像这样:
红色文本是AJAX成功回调,黄色部分是字符计数器。
这是我的jQuery:
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
$('#reg_email').keyup(function(){
var min_password_chars = 6;
var email_input = $('#reg_email').val();
var email_prev = '';
if (email_input.length < min_password_chars)
{
$('.email-check').text('');
if ($('.email-check').children('.yellowish').length == 0)
{
$('.email-check').append('<span class="yellowish"><span class="counter">6</span> to go</span>');
}
$('.email-check .counter').text(min_password_chars - email_input.length);
}
else
{
delay(function(){
$.ajax({
type: 'GET',
url: 'ajax.php?action=check_email',
data: { email: JSON.stringify(email_input) },
success: function(data){
var response = $.parseJSON(data);
$('.email-check').append(response.message);
email_prev += response.sent_email;
}
});
}, 1500);
if (email_input != email_prev)
{
$('.email-check').text('');
}
}
});
这是HTML:
<div class="form-group">
<label for="rep_email">Repeat email</label>
<input type="email" class="form-control" id="rep_email" name="email_rep" placeholder="Enter your email" required>
<p class="email-check pull-right validate-note"><span class="yellowish"><span class="counter">6</span> to go</span></p>
</div>
我可能做错了什么? 我的逻辑在哪里使我失望?
您的ajax调用是双重异步的,因此这可能会使调试和结果感到困惑。 这种类型的东西实际上很难用断点调试。 我发现我经常不得不在代码中放入console.log()
语句,这样我才能实时查看事件的实际顺序。
else
子句的执行部分在第一次遇到else
子句之后的某个时间执行,并且由于您的delay()
和AJAX调用的异步特性而被双重延迟。 如果您不针对特定情况进行编码,则这将导致调试困难,并且很容易导致编程错误。
首先,它们是异步的,因为您使用的是delay()
,我假设它是setTimeout()
。 这意味着您甚至要到某个时候才开始进行Ajax调用。 其次,它们是异步的,因为它们是异步ajax调用。 因此,他们在else
分支执行之后的某个时间调用成功处理程序。 实际上,您可以在其他字符完成执行之前先键入它们。
您还会遇到关闭问题,即您可能在成功处理程序中使用的数据与最初发送ajax调用时的数据不同(因为自声明ajax调用以来它已更改)。
在下面的代码中,我应用了这些修复程序:
这样做并不是在计划下一个ajax调用时取消任何正在进行的ajax调用,但这只是服务器效率问题,而不是正确性问题。 您的代码还假定将同时处理多个在飞行中的ajax调用,并按顺序返回。 在现实世界中通常是这种情况,但如果不进行编码以明确排序,就无法保证。
var emailTimeout;
$('#reg_email').keyup(function(){
var min_password_chars = 6;
var email_input = $('#reg_email').val();
var email_prev = '';
if (email_input.length < min_password_chars)
{
$('.email-check').text('');
if ($('.email-check').children('.yellowish').length == 0)
{
$('.email-check').append('<span class="yellowish"><span class="counter">6</span> to go</span>');
}
$('.email-check .counter').text(min_password_chars - email_input.length);
}
else
{
clearTimeout(emailTimeout);
emailTimeout = setTimeout(function(){
// get latest email value, might have changed
var latest_email_input = $('#reg_email').val();
// if it's not long enough, don't send to the server
if (latest_email_input.length < min_password_chars) return;
$.ajax({
type: 'GET',
url: 'ajax.php?action=check_email',
// always retrieve latest value of data (may have changed)
data: { email: JSON.stringify(latest_email_input) },
success: function(data){
var response = $.parseJSON(data);
$('.email-check').append(response.message);
email_prev += response.sent_email;
}
});
}, 1500);
if (email_input != email_prev)
{
$('.email-check').text('');
}
}
});
仅供参考,这是您的酷炫延迟功能的更通用的版本,只需传递用于不同用途的不同标记字符串,即可同时用于多种不同用途:
var delay = (function(){
var timers = {};
return function(tag, callback, ms){
clearTimeout(timers[tag]);
timers[tag] = setTimeout(function() {
delete timers[tag];
callback();
}, ms);
};
})();
// sample usage
delay("emailKey", fn, 1500);
delay("search", fn, 500);
它看起来像一个竞争条件,由$.ajax
和delay()
复合。 在事件循环的下一个滴答之前,您的ajax调用不会触发,因此退出if块后,将附加您的ajax返回的消息。
我将执行以下操作:
这是我将其重写的方式:
$('#reg_email').keyup(_.debounce(function() {
$('.email-check').text('');
var min_password_chars = 6;
var email_input = $('#reg_email').val();
var email_prev = '';
if (email_input.length < min_password_chars) {
if ($('.email-check').children('.yellowish').length == 0) {
$('.email-check').append('<span class="yellowish"><span class="counter">6</span> to go</span>');
}
$('.email-check .counter').text(min_password_chars - email_input.length);
} else {
$.ajax({
type: 'GET',
url: 'ajax.php?action=check_email',
data: { email: JSON.stringify(email_input) },
success: function(data){
var response = $.parseJSON(data);
$('.email-check').append(response.message);
email_prev += response.sent_email;
}
});
}
}), 1500);
假设您在email字段中输入abcdefgh
,然后在其上退格,这将导致5个ajax调用,由于delay
,它们至少分散了5 * 1.5 = 7.5秒。
要计算这一点,请从abcde
开始:
abcde
尚未。 abcdef
-ajax调用1 abcdefg
-Ajax通话2 abcdefgh
-Ajax通话3 abcdefg
-ajax调用4 abcdef
-ajax调用5 编辑字段后,ajax调用将继续,两次调用之间至少间隔1.5秒。
此外,如果您使用断点,那么当您暂停程序时,这将暂停延迟。 当您再次运行它时,它将继续它从上次中断的地方开始,并带有排队的ajax事件,使其看起来像是它们自己在运行,但实际上是上次运行遗留下来的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.