地味にハマってしまったので備忘録として残しておきます。
今回問題となったのが以下のコード。
var hoge = {};
$.getJSON("http://sample.com/sample.json", {"data":"data"}, function(json) {
hoge = json;
});
console.log(hoge);
これを実行すると取得してきたjsonがコンソールに表示されると思いますよね?
しかし上記コードを実行してもコンソールには何も表示されない、つまり変数hogeは空っぽのままなのです。
なぜこんなことになってしまうかというと、$.getJSONは非同期前提の関数なので$.getJSONでの取得が終わらないうちにその下のconsole.logがコールされてしまい、結果として値が空のままになってしまうのです。
$.getJSONではなく$.ajaxでasync:false設定
この現象を解決するには以下のコードを使います。
var hoge = {};
$.ajax({
url: "http://sample.com/sample.json",
dataType: 'json',
async: false,
data: { "data" : "data" },
success: function(json) {
hoge = json;
}
});
console.log(hoge);
これでjsonの中身がコンソールに表示されます。
$.ajax関数はasyncという設定で同期、非同期を切り替えることができるので、async:falseで同期設定にすることでjsonの取得を待って以下のコードが実行されるようになった、というわけです。
この一連の処理を「ブロッキング」というらしいです。
jsonがらみのことなのに$.getJSONで解決できないというのも面白い話ですけどね。