【发布时间】:2012-03-16 08:42:29
【问题描述】:
经过一些调试,似乎每个语句之后的代码在每个语句完成之前正在执行。
我还注意到每个函数循环了两次。
会发生这样的事情:
- 单击#ProductsSubmit 元素
- 弹出警报并显示以下消息:“事件已触发”--(#ProductSubmit 点击事件仅触发一次。警报框仅弹出一次。)
- 通过使用 Firefox firebug,我可以看到 get 函数被调用了 4 次。只有 2 个 .AddProduct 元素。查看包含抓取的元素 ID 的 URL 时,我可以看到 .each() 函数循环了两次,但请记住 #ProductSubmit 点击事件仅被触发一次。
- 第一个警报 (ErrorFound) 弹出值为 0。我验证 get 回调正在触发 if(VerifyData['Valid']!='Yes') 语句。所以 if 语句 100% 的时间都是正确的(用于调试)
- 触发了设置超时。警报弹出窗口将 alert(ErrorFound) 显示为 1。
所以看起来警报(ErrorFound)在每个语句中的 ErrorFound 设置为 1 之前被触发。但是当我对其进行延迟时,它似乎赶上了并显示了应该是什么值,即 1。
var ErrorFound;
$(document).ready(function(){
$(document).delegate("#ProductsSubmit", 'click', function(){
alert('Event Triggered');
ErrorFound = 0;
$(".AddProduct").each(function(){
var IDToConfirm = $(this).attr('id');
var SKUToConfirm = $(this).val();
$("#"+IDToConfirm).removeClass("InputError");
$.get('http://www.example.com/script.php?s='+SKUToConfirm+'&ut='+IDToConfirm, function(data) {
var VerifyData = jQuery.parseJSON(data);
if(VerifyData['Valid']!='Yes') { ErrorFound = 1; $("#"+VerifyData['ID']).addClass("InputError"); }
});
});
// Alert box shows value as 0
alert(ErrorFound);
setTimeout("AlertError()", 5000);
return false;
});
});
function AlertError() {
// Alert box shows value as 1
alert(ErrorFound);
}
发生了什么事?我尝试了很多变通方法,但没有找到任何可行的方法。
【问题讨论】:
-
$.get()是异步的。阅读 Promises。 -
.delegate()已弃用,请使用.on() -
从不将字符串传递给
setInterval()或setTimeout()。这样做与使用eval()一样糟糕,一旦使用变量,它就会导致代码不可读且可能不安全,因为您需要将它们插入字符串而不是传递实际变量。正确的解决方案是setInterval(function() { /* your code *) }, msecs);。这同样适用于setTimeout()。如果只想调用单个函数不带任何参数,也可以直接传函数名:setInterval(someFunction, msecs);(注意函数名后面有no()) -
为什么所有变量都以大写字母开头?通常,这是命名构造函数的常见做法。看到你的变量都是蓝色的......
-
我从不使用 SetTimeout 函数。只是在这里用于调试目的。