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 ループ本体よりも大きいことです。これは、同じ変数を毎回異なる値に設定することを意味します。そのため、コールバック関数が最終的に呼び出されると、変数は最終的な値を持ちます。

これを修正する 1 つの方法は、リクエストの作成を次のような新しい関数に移動することです。

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 に答える