AngularJSの$qサービスでpromise/deferredパターンのサンプル作成

AngularJSでは、$http、$timeout、$intervalサービスなどではpromises/deferredパターンで実装されていて、サービス利用時にpromiseオブジェクトがリターンされ、非同期処理を行う事が出来ます。$qサービスを使うとpromises/deferredパターンのサービスなどを定義する事が出来ます。

デモとコードサンプルはこちら
 
※目次をクリックすると目次の下部にコンテンツが表示されます。

promise/deferredパターンの概要
・promise/deferredパターンでは、ある一定時間後(タイムアウト後、インターバル経過後、サーバーからのレスポンス受信後など)に実行したい作業内容を登録し、そのまま待機状態にせず(非同期処理)、実行出来る状態になった段階で登録した作業を実行させる事が出来る。
 
・promise/deferredパターンでは、promiseオブジェクトとdeferredオブジェクトの二つが必要。ある一定時間後に準備が出来た事を通知する仕組みが必要だが、deferredオブジェクトが送信側、promiseオブジェクトが受信側となる。
 
・promiseオブジェクトは、ある一定時間後に実行したい処理内容を登録する事が出来るので、deferredオブジェクトからの通知を受けると登録した作業を実行させる事が出来る。
 
・$httpサービスなどはpromise/deferredパターンで実装されているので、サービスを利用するとpromiseオブジェクトがリターンされ、サーバーからのレスポンス受信後の作業内容を定義して非同期処理を実行させる事が出来る。

AngularJSの$qサービスの使用方法
$httpサービスなどはpromise/deferredパターンで実装されているので、リターンされたpromiseオブジェクトを使用するだけで済むが、自分でpromise/deferredパターンを作成する場合は、$qサービスを使ってdeferredオブジェクトを生成する必要がある。
 
1)deferredオブジェクト
 
①deferredオブジェクトを生成
 
var deferred = $q.defer();
 
②deferredオブジェクトと対になるpromiseオブジェクト
 
上記①で生成したdeferredオブジェクトのpromise属性で取得出来る。
deferred.promise
 
③deferredオブジェクトのメソッド
 
●deferred.resolve(result)
 
・上記②のpromiseに、正常に実行できる状態になった事を通知。
 
・引数のresultを対になるpromiseオブジェクトのthenメソッドのsuccessコールバック関数の引数に渡す。
 
●deferred.reject(reason)
 
・上記②のpromiseに、サーバーからのレスポンスエラーなどで正常に実行できる状態にならなかった事を通知。
 
・引数のreasonを対になるpromiseオブジェクトのthenメソッドのerrorコールバック関数の引数に渡す。
 
●deferred.notify(value)
 
・promiseオブジェクトの実行のステータスを更新し、promiseがresolveまたはrejectされるまで繰り返し呼ばれる。
 
・引数のvalueを対になるpromiseオブジェクトのthenメソッドのnotifyコールバック関数の引数に渡す。
 
2)promiseオブジェクトのメソッド
 
●deferred.promise.then(success, error, notify)
 
deferredオブジェクトのresolve、reject、notifyメソッドが実行され、promiseオブジェクトに通知された時に実行するコールバック関数を登録する。

サンプルコード
promise/deferredパターンを使ってコントローラからサービスに対し処理を依頼し、実行できる状態(タイムアウト後)になってからサービス側から受け取ったメッセージを表示するサンプルを作成しました。
 
①コントローラで$qサービスを利用できるように指定
 
demoApp.controller(‘qCtrl’, function($scope,qService,$q) {
 
②コントローラでdeferredオブジェクト生成
 
var deferred = $q.defer();
 
③準備完了後、実行したい処理を登録
 
deferred.promise.then(function (result) {
$scope.msg = result;
},function (reason) {
$scope.msg = reason;
})
 
④サービスに処理を依頼
 
qService.q_get(deferred,tf);
 
⑤サービス側からコントローラ側へ準備完了を通知

if (tf) {
  deferred.resolve("サービス処理成功 全回数:" + totalnum );
} else {
  deferred.reject("サービス処理失敗 全回数:" + totalnum );
}

 
デモとコードサンプルはこちら

関連記事の目次

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください