2017-03-08 14 views
0
loadJSON(path, callback) { 
    console.log("path: " + path); 
    var xobj = new XMLHttpRequest(); 
     xobj.overrideMimeType("application/json"); 
    xobj.open('GET', path, true); 
    xobj.onreadystatechange = function() { 
      if (xobj.readyState == 4 && xobj.status == "200") { 
      callback(xobj.responseText); 
      } 
    }; 
    xobj.send(null); 
} 

上記はjsonファイルにローカルでアクセスする関数です。 その後、 `foobar() 'から検索されたデータを解析します。 しかし、コールバック機能の「外部」から、変数「json」にアクセスすることはできません。 私は同様のSOの質問と非同期の概念を検索しましたが、まだそれを解決する方法を見つけることができませんでした。javacriptのコールバック関数の "outside"変数へのアクセス

function foobar() { 
    var json; 
    loadJSON("data.json", function(response) { 
     json = JSON.parse(response); 
     console.log(json[0].name); // Successfully shows the result 
    }); 
    console.log(json[0].name); // TypeError: json is undefined 
} 

コールバックの変数「外部」にアクセスする方法はありますか?

+0

http://stackoverflow.com/questions/14220321/how-do-i-return-from-as-asynchronous-call –

+0

[なぜ私の変数は関数の中で変更した後に変更されないのですか? - 非同期コードリファレンス](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Andreas

+0

両方のリンクをチェックしましたそして今私は理解しています**なぜコールバックの '外部'と呼ばれることができないのですか?今は 'loadJSON()'の中に関数を実装して問題を解決しましたが、それ以外の変数にアクセスすることができます。なぜ私は回避策があるのか​​知りたいのですが。 – HUKS

答えて

2

これは非同期モードに設定されているためです。

console.log(json[0].name); // TypeError: json is undefined 

このコードは、jsonが埋め込まれる前に実行されます。したがって、アクセスしようとするとまだ空になっている可能性があります。この行の3番目の引数は非同期としてそれを定義しています

xobj.open('GET', path, true); 

あなたは

xobj.open('GET', path, false); 

を置くことを試みることができる。しかし、それはもう非同期ではなく、ユーザーが終了要求のために待機する必要があります、だから、コールバックメソッドが呼ばれていなくても前に呼び出されていないときに、 'json' varを使うのが良いでしょう。非同期モードをオンにする。 これを行うには、コードを再構成する必要があります。

Gerardo Furtadoが投稿したリンクは完全に正確です。確認する必要があります。

編集:私はすでに述べたように、他のユーザーも、非同期:偽のは非常に良いではありませんので、私は私の答えを編集しています:

function foobar() { 
    var json; 
    loadJSON("data.json", function(response) { 
     json = JSON.parse(response); 
     // Call another function with json that is now filled with data 
     triggered(json); 
    }); 
} 

function triggered(json) { 
    console.log(json[0].name); 
    // Do your work on json 
} 
+0

は実際に私の問題を解決するので答えとして受け入れます。 – HUKS

+0

@HUKS 'async:false'はほとんどの場合**答えではありません...問題の中核とその解決方法を理解するには、"可能な重複:... "リンクを実際に見てください。 – Andreas

+0

私はこれを答えとして受け入れた理由は、自分の目標はUIだけでブラウザを使ってオフラインで実行されるスクリプトなので、私はサーバーの応答の問題について心配する必要はないと考えました。私はこれがほとんどの非同期のケースでは答えではないかもしれないことに同意します。 – HUKS

1

非常に簡単です。関数外のjson変数を宣言します。これにより、変数にグローバルスコープが与えられます。この関数はjsonをオーバーライドするためだけに呼び出され、jsonはスクリプトのどこでも使用できます。

関連する問題