$.Deferredは非同期処理を行うための便利なモジュールですが、
その使い方についてはYahooデベロッパーネットワークの 爆速でわかるjQuery.Deferred超入門がとても分かりやすくお世話になりました。
非同期処理を時系列で記述できるのでとても便利ですが、主に使う4つのメソッドの使い所についての自分メモ書きです。
resolved,rejected時の動作を同時に定義できるthen()
promiseオブジェクトが、resolveにもrejectにもなる場合、
then()でそれぞれの時のコールバックを定義します。
function hoge() {
let defer = $.Deferred();
if (isFuga()) {
defer.resolve();
return true;
} else {
defer.reject();
}
return defer.promise();
}
hoge().then(
/**
* resolve時の動作
*/
function() {
return $.Deferred().resolve().promise();
},
/**
* reject時の動作
*/
function() {
return $.Deferred().resolve().promise();
}
).then(
/**
* resolve時の動作
*/
fucntion() {
return $.Deferred().resolve().promise();
},
/**
* reject時の動作
*/
function() {
return $.Deferred().resolve().promise();
}
);
例の関数が非同期処理ではないのですが・・
例えばAjaxを使って外部リソースを取得しその結果次第で処理を変えたい場合があるときに使うと便利です。
第2引数のreject時のコールバックは省略もできます。
resolvedで実行されるdone()
then()
でもresolve時の動作を定義できますが、then()
と違うのは、 done()
を連結してもそれは順次実行されないことでしょうか。
// hoge()が返すpromiseがresolveだとする
hoge().then(
/**
* resolve時の動作
*/
function() {
// 実行順1
return $.Deferred().resolve().promise();
},
/**
* reject時の動作
*/
function() {
return $.Deferred().reject().promise();
}
).then(
/**
* resolve時の動作
*/
function() {
// 実行順2
return $.Deferred().resolve().promise();
},
/**
* reject時の動作
*/
function() {
return $.Deferred().resolve().promise();
}
).done(
function() {
// 実行順3
// このdoneと下のdoneは同時に実行されます
}
).done(
function() {
// 実行3
// このdoneと上のdoneは同時に実行されます
}
);
爆速でわかるjQuery.Deferred超入門にも書かれていましたが、 done()
を複数書いても、それは done()
のコールバックを2つ定義しただけで、順次実行にはなりません。
rejectedで実行されるfail()
fail()
は コールバックの中で新たにresolvedなpromiseをreturnしない限り、rejectedが継続されるため done()
は実行されません。try-catchの catchのイメージ。
// hoge()が返すpromiseがrejectedだとする
hoge().fail(
function() {
// 実行1
// 失敗時の処理
}
).done(
function() {
// 実行されない
}
);
必ず実行されるalways()
最後の後始末処理に使える always()
。
rejectedでもresolvedでも実行されるので、成功・失敗に関わらず実行したい処理があるときに使います。
try-catch でいえば、finally。
// hoge()が返すpromiseがrejectedだとする
hoge().fail(
function() {
// 実行1
// 失敗時の処理
}
).done(
function() {
// 実行されない
}
).always(
function() {
// 実行2
// 後始末の処理
}
);