$.getJSONで得たJSONをグローバル変数に格納するには、$.ajaxでasync: falseで解決

地味にハマってしまったので備忘録として残しておきます。

今回問題となったのが以下のコード。

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で解決できないというのも面白い話ですけどね。