Deferredその4:always()による解決済みと拒否のコールバックの共通化
always()による解決済みと拒否のコールバックの共通化
解決済みと却下の状態のコールバックは以下の様になります。
・.resolve()で解決済みにしたら.done()がコールバックされる
・.reject()で却下にしたら.fail()がコールバックされる
この解決済みと却下の両方に同じ後処理を付けたいとしたらどうでしょう?
.done()と.fail()の両方に同じ処理を書けば良いというか、.done()の共通後処理部分をコピーして.fail()の終わりの方にペーストすれば出来ることを出来ますが、可読性がかなり劣りますし修正した場合に.fail()にその部分をコピペし直すという手間も発生します。
そこで.always()の登場です、この.always()は解決済みと却下のどちらでもコールバックされます。
Deferredにおいてalwaysをコールバックさせるサンプル
これについても、文章より実際のコードを見たほうが分かりやすと思いますので、サンプルを示します。
リクエストのパラメーターに文字列を囲んで返すテスト用のPHP
1.このパラメータは"contents"があり、"パラメーターのキーをcontentsとして受け取った値は"と"です。"で囲んだものを出力。
test-deferred-always.php
// ※これはhtmlではなくphpファイルです、<?phpと?>で囲んでください $contents = $_SERVER["REQUEST_METHOD"] == "GET" ? $_GET["contents"] : $_POST["contents"] ; echo "パラメーターのキーをcontentsとして受け取った値は" . $contents . "です。";
always()による解決済みと拒否のコールバックの共通化のjQueryサンプルコード
1.getAjaxPromise()はDeferredのPromiseオブジェクトを返す
2.ajax通信の結果により、Promiseオブジェクトの状態は解決済みか拒否となる
3.var ajaxPromise_1は解決済みの状態、var ajaxPromise_2は存在しないurlをリクエストするため拒否の状態となる
4.ajaxPromise_1、ajaxPromise_2ともに.always()はコールバックされる
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <style type="text/css"> <!-- div {border: 1px solid black;} --> </style> <script src="../../js/jquery-1.12.2.min.js"></script> <script> $(function(){ // 普通に成功して状態が「解決済み」のPromiseオブジェクトが返される var ajaxPromise_1 = getAjaxPromise("test-deferred-always.php", "contents=test-deferred-always"); // 存在しないphpファイルなので、404エラーが返され状態が「拒否」のPromiseオブジェクトが返される var ajaxPromise_2 = getAjaxPromise("test-deferred-always-notfound.php", "contents=test-deferred-always"); function getAjaxPromise(ajaxUrl, ajaxData){ // Deferredオブジェクト作成 var defer = new $.Deferred; $.ajax({ url: ajaxUrl, data: ajaxData, success: function(data) { // Deferredの状態をresolveとする。 // これによりコールバック関数は.done()となる。 defer.resolve(data); }, error: function(jqXHR, textStatus, errorThrown) { // Deferredの状態をrejectとする。 // これによりコールバック関数は.fail()となる。 defer.reject(jqXHR, textStatus, errorThrown); } }); return defer.promise(); } // 状態が「解決済み」なので.done()がコールバックされる ajaxPromise_1.done(function(data) { $("div.result_1").text("[ajaxPromise_1]ajax通信で受け取った結果:" + data); }).fail(function(jqXHR, textStatus, errorThrown) { $("div.result_1").text("[ajaxPromise_1]エラーが発生しました。ステータス:" + jqXHR.status); }).always(function(){ $("div.result_1").html($("div.result_1").text() + "<br>(always)成功しようがエラーだろうが呼ばれる"); }); // 状態が「拒否」なので.fail()がコールバックされる ajaxPromise_2.done(function(data) { $("div.result_2").text("[ajaxPromise_2]ajax通信で受け取った結果:" + data); }).fail(function(jqXHR, textStatus, errorThrown) { $("div.result_2").text("[ajaxPromise_2]エラーが発生しました。ステータス:" + jqXHR.status); }).always(function(){ $("div.result_2").html($("div.result_2").text() + "<br>(always)成功しようがエラーだろうが呼ばれる"); }); }); </script> </head> <body> <div class = "result_1"></div><br><br> <div class = "result_2"></div> </body> </html>