2011-08-12 2 views
0

私が欲しいのは、ある機能から取り出されたデータを別の機能に表示することです。私は、グローバル変数を使用すると、私はこれを達成することができると言われたWhat is the best way to store a value for use in a later function? I'm hearing global variables are evilだから私はグローバル変数を使用しましたが、なぜこのコードは '未定義'のアラートを返しますか?

これは私が試みたものです。 http://jsfiddle.net/8j947/17/

アラートとしてグローバル変数を表示しようとすると、定義されていない状態に戻ります(jsfiddleでは表示されない可能性があります)。データが実際には格納されていないためだと思っていますが、私は3週間しかコーディングしていないので、何を知っていますか?もしあなたが私が間違っていたことを私に見せたり、素晴らしい解決策を提案したりして、あなたが私を助けてくれるかもしれません。

+0

グローバル変数には何も問題はありません。すべてをグローバルにしないでください。 AJAXのAは "非同期"であることを覚えておいてください。これはあなたがリクエストしたことを意味し、結果は後でいつか戻ってきます。したがって、すぐに結果を確認すると、まだそこには存在しない可能性があります。 "コールバック"は、応答が来たときにそれを受け取る関数です。それが鍵です。 –

+0

@Diodeus確かに(グローバル変数には何か問題があります)、避けてください。理想的には、あなたのアプリケーション/ Webサイト/会社/ ...を表すグローバル変数を 'YAHOO'や' StackOverflow'のように1つだけ使用し、それをあなたの名前空間として使うのが理想です。 –

+0

@Davis jsFiddleデモの変数は、ページロードハンドラ内で宣言しているので、グローバル変数ではありません。 –

答えて

0

getCrossDomainJsonが呼び出され、getCrossDomainJsonに渡されたコールバック関数が呼び出される直前に、アラート機能が下部に実行されています。 somePropertyプロパティはコールバック関数内で設定されているため、アラートでそのプロパティを参照すると、実際にはまだ設定されていません。

アラート関数に名前を付け、コールバック関数が完了した後で別の場所にコールします。

function getCrossDomainJson(url, callback) { 
    $.ajax({ 
     url: "http://query.yahooapis.com/v1/public/yql?callback=?", 
     data: { 
      q: 'select * from xml where url="' + url + '"', 
      format: "json" 
     }, 
     dataType: "jsonp", 
     success: callback 
    }); 
} 

var MyStatus = {}; 
getCrossDomainJson("http://xdiscgolfplanetx.channel-api.livestream-api.com/2.0/getstream", function(data) { 
    // data is in JSON format: 
    console.dir(data); 
    if (data && data.query && data.query.results && data.query.results.channel) { 
     var isLive = (data.query.results.channel.isLive); 
     MyStatus.someProperty = data.query.results.channel.isLive; 
    // alert (isLive) 
     if (isLive == 'true') { 
      alert ('working') 
     } 
     alertSomeProperty();   // now that the someProperty property has been set and MyStatus 
             //is global, you'll see that you can refer to it even outside of this block 
    } 
}); 

function alertSomeProperty(){ 
    alert (MyStatus.someProperty) 
} 
+0

どうすればそれをやりますか?回答をありがとう – davis

+0

@Davisさて、Ajaxコールバック関数内からアラートを呼び出すと、それが最初の目的です。または、他の関数の中にアラートを置き、コールバック内から他の関数​​を呼び出すこともできます。 –

+0

@Simeだから私はコールバックから呼びました(私は思う)、それは未定義です。 http://jsfiddle.net/8E6vH/ – davis

0

これは、非同期プログラミングを使用する際の古典的な誤りです。関数a()、b()、c()の順に呼び出して、実行順序を1つずつ考えることはできません。任意の形式のajax呼び出しを使用する場合、通常は非同期です。つまり、関数を呼び出すと実行が開始されるだけです。

これはバックグラウンドで実行され、残りのjavascriptは実行されて終了します。その後、いつか、ajax呼び出しが完了し、それが成功関数と呼ばれます。その成功関数または成功関数から呼び出す他のコードからのみ、実際にあなたのajax呼び出しの結果を使用することができます。だから、本質的に何をしなければならないのかは、ajax呼び出しを開始してから、あなたのjavascriptコードが終了することです。その後、ajax呼び出しが完了したときに実行する必要がある処理の残りの部分を実行するsuccess関数を記述します。その時点で、JSONデータがあり、それを使って自分が望むことができるようになります。そのデータを受け取り、他の機能を呼び出すことができます。データを操作して操作することができます。

したがって、成功ハンドラからの2番目の実行ステップを実行します。取り出されたデータで何をする必要があるものであれ、成功ハンドラから開始する必要があります。だから、

、あなたがやってみたかった実行の流れがこのだった場合:

a(); 
b(); 
getJSONdata(); 
c(); 
d(); 

あなたはこのようにそれを構築する必要があります:

C()およびD()がある
a(); 
b(); 
getJSONdata("xxx", function(data) { 
    c(data); 
    d(); 
}) 

function c(myData) { 
    // do something with the passed in data 
} 

成功関数でJSONデータを取得することから起こり、データが利用可能になった後にのみ呼び出されます。

+0

要求が終了した後に関数を使用したいのですが、どのようにして未定義であるのを防ぐことができますか? – davis

+0

上記の私の2番目の例を参照してください。成功ハンドラからのデータを使用する関数を呼び出し、その関数にデータをパラメータとして渡します。私の例では、これはコードの 'c(data);'行です。あなたのコードが構造化されているように、 'getCrossDomainJson'の中で宣言した関数の中でこれを完了ハンドラとして実行します。 – jfriend00

関連する問題