2010-11-29 17 views
1

コールバック関数の外部でグローバル変数を使用するのに最適な方法は何ですか?ajaxコールバック関数以外の変数を使用する

var icon; 
    $(function(){ 

     $.get('data.xml', function(xml){ 

      icon = xml.documentElement.getElementsByTagName("icon"); 
      //this outputs a value 
      console.log(icon); 
     }); 
     //this is null 
     //How can this maintain the value set above? 
     console.log(icon); 
    }); 
+1

....なんですか? O_o –

+0

あなたは何を達成しようとしていますか? – thejh

+0

どのような値を維持できますか?あなたはより明確にする必要があります。 –

答えて

5

あなたが提供したコードは完全に有効です。実際には、iconの値を維持しています。問題はおそらくget()が非同期で実行され、'data.xml'の後に匿名関数がサーバーから完全にロードされただけです。

  1. コールget('data.xml', function(xml){...})(data.xmlファイルのロードを開始)
  2. コールconsole.log(icon)iconは、この時点ではまだnullである)
  3. (data.xmlの完成:だから、実行の実世界のシーケンスは次のようになりますloading)匿名関数が呼び出され、icon:icon = xml.documentElement.getElementsByTagName("icon")に値が割り当てられます。

あなたがiconの値を持つ何かをしたい場合は、後の「data.xmlには、」あなたはそれを内部の匿名のコールバック関数を実行する必要があります、フェッチされました。このように:

var icon; 
$(function(){ 

    $.get('data.xml', function(xml){ 
     icon = xml.documentElement.getElementsByTagName("icon"); 
     console.log(icon); 
    }); 
}); 

幸運!


注:あなたはまだ匿名関数外あるコードからiconを使用することができますが、匿名関数が実行されたまで、それにアクセスするのを待つ必要があります。これを行うための最善の方法は、独自の機能に依存するコードを入れて、その後、コールバック関数内からその関数を呼び出すことです:

var icon; 
$(function(){ 

    $.get('data.xml', function(xml){ 
     icon = xml.documentElement.getElementsByTagName("icon"); 
     loadIcon(); 
    }); 

    function loadIcon() { 
     console.log(icon); 
     // ... do whatever you need to do with icon here 
    } 
}); 
+0

私はあなたの2番目の解決策を避けようとしていました。しかし、これが唯一の方法だと思われます。さらに悪いことに、setTimeout関数を追加して動作させる必要がありました。ああ! – Mike

+1

@Mike、あなたが何をやっているのかをもう少し詳しく説明する(あるいは別の質問を開く)場合、タイマーを使わずに済むように助けることができます。 (*してください*あなたがそれを避けるのを手伝ってください - タイマーはここではほとんど必要ありません)。ここ – Lee

+0

は詳細http://pastie.org/1333534 – Mike

1

console.log(icon);は、非同期ajaxを実行しているときにその時点で値を持ちません。応答を処理するコード全体を、コールバック関数または呼び出し関数で移動します。

$(function(){ 

    $.get('data.xml', function(xml) { 
     var icon = xml.documentElement.getElementsByTagName("icon"); 
     console.log(icon); 
    }); 
}); 
+0

そのコールバック関数の外で変数を使用する必要があります。 – Mike

+0

@Mike:何のため? – thejh

+1

@Mike、コールバック関数の外では使用できません。コールバック関数が書いたカスタム関数を呼び出すように、コードを再構成することができます。また、カスタムコードを直接コールバック関数に入れることもできます。しかし、ajax呼び出しの後で直接使用する方法はありません。なぜなら、ここでは誰もが非同期であると言っているからです(同期呼び出しを行うことは可能ですが、これは非常に悪い考えです。 –

1

問題は、$.getが要求をキューに入れているが、要求を同期的に実行していないことです。すぐに戻ります。 JavaScriptはマルチスレッドではありません!

console.log(icon)の中でコールバック関数を実行する必要があります。行が実行されている時点で、AJAX呼び出しはまだ完了していません。

グローバルicon変数は、をコールバックから設定します。その点であなたのコードは正しいです。

1

それは、このようなコードを視覚化するのに役立ちます。

var icon; 
    $(function(){ 
     $.get('data.xml', callback); // sends ajax request 
     // next line happens immediately unless ajax request is set to synchronous 
     console.log(icon); // logs undefined 
    }); 
    function callback(xml){ // onsuccess callback happens 
     icon = xml.documentElement.getElementsByTagName("icon"); 
     console.log(icon); // logs Array 
    } 

私は匿名関数を削除し、console.logの後にコールバックを配置しました。他の人は、JavaScriptが実行し続けている間に、非同期的にAJAXコールバックが発生することを指摘しています。