0
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 的函数的名称,所以有人可以给我一个关于语法的提示。或者,如果有更简单的方法......我将不胜感激。

4

2 回答 2

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() 函数。

于 2012-11-08T16:43:14.983 回答
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);
    }
}
于 2012-11-08T16:44:56.100 回答