これは無知な私の失敗談です。
知った気でいると足元をすくわれるというか無駄な努力をする羽目になるという備忘録です。
非同期で書いた
元の要件としては、とあるXML中にある値が含まれているかどうかを判定する、といったものでした。
そのためjQueryでxmlを取得して使うことを考え、以下のようなメソッドを実装しようとしていました。
※コールバックや判定の処理を省略しています。
function checkXml() {
var deferred = $.ajax({
dataType: 'xml',
url: 'test.xml'
});
/* 呼んだ先でコールバックを登録 */
return deferred;
}
XMLHttpRequestで同期処理に書き直した
ところが実際にはメソッドを呼んだ返り値としてtrue or falseを得たいということになったため、
同期的にxmlを取得する方法を調べてみました。
するとXMLHttpRequestのopenで第三引数にfalseを渡してやれば同期的に実行される、ということがわかりました。
そのため、以下のようにしました。
function checkXml(str) {
var xmlHttp;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", 'test.xml', false);
xmlHttp.send(null);
var doc = $.parseXML(xmlHttp.responseText);
var xml = $(doc);
var ret = false;
/* jQueryを使ってstr が含まれるかどうか判定 */
return ret;
}
XMLHttpRequest.responseXMLを使う
先ほどの例で、xmlHttp.responseTextをjQueryでXMLパースしてからjQueryオブジェクトにしてやればいいやと安易に考えていたのですが、よくよくXMLHttpRequestの仕様を調べてみるとresponseXMLなる便利なプロパティがあることを知って書き直しました。
function checkXml(str) {
var xmlHttp;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", 'test.xml', false);
xmlHttp.send(null);
var xml = $(xmlHttp.responseXML); // わざわざパースしなくてもdocumentが取れる
var ret = false;
/* jQueryを使ってstr が含まれるかどうか判定 */
return ret;
}
結局jQuery.ajax()を使う
その後 jQuery.ajax() のドキュメントを見ていたら 実は非同期フラグがある、と気が付きました。
そして結局以下のような形になりました。
返却値を取るためにコールバックと判定処理が入る程度でほとんど最初と同じようなものになってしまいました。
function checkXml(str) {
var xml;
$.ajax({
async: false, // 非同期オプション(デフォルト true)
dataType: 'xml',
url: 'test.xml',
success: function(data) {
xml = $(data);
}
});
/* jQueryを使ってstr が含まれるかどうか判定 */
return ret;
}
なんとなくネットで見つけたやり方とかを仕様も確認せず使うのは危険だということを改めて思い知りました。