function updateItem(str)
{
var stocks =new Array("GOOG","MSFT","AAP","JDAS","G");
for(var i=0; i<stocks.length;i++)
{
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
alert ("Browser does not support HTTP Request");
return;
}
var url="php/updateCart.php";
url=url+"?q="+stocks[i];
url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange= function(){
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{
document.getElementById(stocks[i])
.innerHTML=xmlHttp.responseText;
}
}
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
}
function startOff()
{
if(interval != -1)
{
clearInterval(interval);
}
interval = setInterval(function() {updateItem()}, 1000);
}
我正在尝试在一个区间中更新表单中的多个分区,问题是for循环将快速完成请求。我没有意识到这一点,当我慢慢推入时,我发出了一堆警报并注意到...我知道你可以用setTimeout做到这一点,但语法我似乎无法正常下去。由于我没有函数的名称来检查readystate,有人可以给我一个语法提示。或者,如果有更简单的方法...我会很感激。
答案 0 :(得分:1)
您可以使用闭包。将单个值传递给不同的函数,并且可以在回调中访问它。示例代码可以是这样的:
function updateAllItems(str) {
var stocks =new Array("GOOG","MSFT","AAP","JDAS","G");
for(var i=0; i<stocks.length;i++) {
updateItem(str, stocks[i]);
}
}
function updateItem(str, stock) {
var xmlHttp=GetXmlHttpObject();
if (xmlHttp==null) {
alert ("Browser does not support HTTP Request");
return;
}
var url="php/updateCart.php";
url=url+"?q="+stock;
url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange= function(){
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
document.getElementById(stock).innerHTML=xmlHttp.responseText;
}
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
function startOff() {
if(interval != -1) {
clearInterval(interval);
}
interval = setInterval(function() {updateAllItems()}, 1000);
}
编辑:添加了startOff()函数。
答案 1 :(得分:1)
编辑:我把事情搞砸了,认为javascript有块范围。当你试图用我想的那么多语言解决问题时会发生这种情况。问题仍然是一样的,但解决方案不是。我仍然不会使用您使用的超时(或在完成上一个请求时启动下一个请求)解决此问题,因为我认为这不是正确的方法。相反,我将解决超时技术仅试图解决的潜在问题。
问题不在于for循环“太快”了。问题是您在回调函数中使用的变量的范围大于for循环体。这意味着您每次都将相同的变量设置为不同的值。因此,当最终调用回调函数时,变量将具有最终值。
解决此问题的一种方法是将请求的创建移动到这样的新函数:
function updateAllItems()
{
var stocks =new Array("GOOG","MSFT","AAP","JDAS","G");
for(var i=0; i<stocks.length;i++)
{
updateItem(stocks[i]);
}
}
function updateItem(stock)
{
var xmlHttp=GetXmlHttpObject(); // Do note, we need the var keyword here to
// make sure this variables uses this scope
// rather than global scope
if (xmlHttp==null)
{
alert ("Browser does not support HTTP Request");
return;
}
var url="php/updateCart.php";
url=url+"?q="+ stock;
url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange= function(){
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{
document.getElementById(stock)
.innerHTML=xmlHttp.responseText;
}
}
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
这可能是更容易理解的方式,但我个人更喜欢以下方式。它基本上做了同样的事情,但是使用一个Javascript技巧和我们立即调用的匿名函数,我们不再需要这样的单独函数,但可以改为处理这个内联:
function updateAllItems()
{
var stocks =new Array("GOOG","MSFT","AAP","JDAS","G");
for(var i=0; i<stocks.length;i++)
{
(function ()
{
var xmlHttp=GetXmlHttpObject(); // Do note, we need the var keyword here to
// make sure this variables uses this scope
// rather than global scope
var i2 = i;
if (xmlHttp==null)
{
alert ("Browser does not support HTTP Request");
return;
}
var url="php/updateCart.php";
url=url+"?q="+ stocks[i];
url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange= function(){
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{
document.getElementById(stocks[i])
.innerHTML=xmlHttp.responseText;
}
}
})();
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
}