0

下のコードで最初のconsole.logにオブジェクトが表示されているのに、2番目のコードが未定義である理由がわかりません。この問題を解決するにはどうすればよいですか?

var listOfTweets = [];

for(var k = 0; k < search.length; k++){
    $.getJSON(searchURL, function(tweets){                              
        listOfTweets[k] = tweets;
        console.log(listOfTweets[k]);                               
    });
    console.log(listOfTweets[k]);
}
4

4 に答える 4

6

getJSONは非同期で実行され、最後のconsole.logは割り当て前に実行されます。

私はあなたが実際に何を望んでいるのかわからないので、あなたが何をすべきかをあなたに言うのは難しいです。覚えておく必要があるのは、実行順序です。

このコードでは

 $.getJSON(searchURL, function(tweets){
          console.log("done");
    });
    console.log("Request send");

最初に発生するのはリクエストが送信されるsearchURLことです。次は「リクエスト送信」がコンソールに出力され、ブラウザがリクエストへの応答を受信するとすぐに関数が呼び出されて「完了」します。コンソールに印刷する

さらに、kが閉じられ、コールバックのすべての呼び出しで同じ値になるため、コードにクロージャの問題があります(1)

その問題を回避するには、自己実行関数を使用できます

for(var k = 0;k<10;k++){
    $.getJSON(searchURL, (function(i){
          return function(tweets){  
                         console.log("done for " + i);
                 }
     }(k));
    console.log("Request send for " + k);
 }

kは関数の引数としてすぐに使用されることに注意してください。引数の値は、コールバックとして関数returnによって参照できるように格納され、kがインクリメントされても変更されません。これまでと同じように行うと、すべてのコールバックが同じオブジェクトを参照しているため、kの値もすべて同じになります。

(1)ループが終了する前に一部が戻ってこない限り

于 2012-05-30T18:07:08.800 に答える
3

$.getJSON呼び出しはすべて非同期で行われます。最後の「console.log」は、getJSON呼び出しが行われる「前」に呼び出される可能性があります。

于 2012-05-30T18:09:16.797 に答える
1

次のようにkを保存してみてください。

var listOfTweets = [];

for(var k = 0; k < search.length; k++){
    $.getJSON(searchURL, function(tweets){    
        var kk = k; // saved!!                          
        listOfTweets[kk] = tweets;
        console.log(listOfTweets[kk]);                               
    });
    console.log(listOfTweets[k]);
}

したがって、kがインクリメントされると、kk保存したものには影響しません。

于 2012-05-30T18:12:09.077 に答える
1

kの現在の値をコールバックのスコープに保存するには、クロージャが必要になります。それ以外の場合は、コールバックが実行されるループの後kと同じです。search.lengthまた、塗りつぶしを使用できるようになる時期については、 JavascriptのコールバックタイミングlistOfTweetsを参照してください。

var listOfTweets = [];
var search = [url1, url2, ...];

$.each(search, function(k, searchURL) {
    $.getJSON(searchURL, function(tweets){                              
        console.log(listOfTweets[k] = tweets);         
    });
});

// After all the ajax request completed, you will be able to
console.log(listOfTweets);
于 2012-05-30T18:24:40.413 に答える