目次
Promiseとは
非同期処理に使用するオブジェクト
使い方
まず$qサービスを使用するため以下の形を作る
var app = angular.module('app', []); app.controller('Ctrl', function($q) { });
そして非同期処理用の関数を作成。var deferred = $q.defer();で非同期処理に必要なDeferredオブジェクトを作成して処理の最後にreturn deferred.promiseで返す
function async() { var deferred = $q.defer(); // この中に処理を記述 return deferred.promise; }
名前を受け取ってHello付けて返す処理の場合はこのようになる
function asyncHello(name) { var deferred = $q.defer(); deferred.resolve('Hello, ' + name); return deferred.promise; }
deferred.resolve()は成功時のpromise処理
promise.then(function(){})を追加
引数部分はこの場合deferred.resolve('Hello, ' + name)の内容になる
var promise = asyncHello('sato'); promise.then( function(msg) { r.innerHTML = msg; } );
1秒遅らせて処理したい場合
$timeoutサービスを追加してvar deferred = $q.defer();とreturn deferred.promise;の間を$timeoutで囲む
function asyncHello(name) { var deferred = $q.defer(); $timeout(function() { deferred.resolve('Hello, ' + name); }, 1000); return deferred.promise; }
失敗時のpromise処理 reject()
成功時のpromise処理はresolve()なのに対し、失敗時の処理にはreject()を使用する。例えばnameが文字列の時は成功、文字列以外の時は失敗の処理をしたい場合は下記のようになる。
then()内の第1引数にresolve、第2引数にrejectのコールバック関数を記述する
var app = angular.module('app', []); app.controller('Ctrl', function($q, $timeout) { function asyncHello(name) { var deferred = $q.defer(); $timeout(function() { if(typeof(name) === 'string') { deferred.resolve('Hello, ' + name); } else { deferred.reject(name + 'は文字列ではありません。'); } }, 1000); return deferred.promise; } var r = document.getElementById('result'); var promise = asyncHello(326); promise.then( function(msg) { r.innerHTML = msg; }, function(msg) { r.innerHTML = msg; } ); });
通知のpromise処理 notify()
通知の処理にはnotifyを使用する。成功、失敗に関わらない処理に使用。
then()内の第3引数にnotifyのコールバック関数を記述する
var app = angular.module('app', []); app.controller('Ctrl', function($q, $timeout) { function asyncHello(name) { var deferred = $q.defer(); $timeout(function() { deferred.notify(name + 'を受け取りました。'); if(typeof(name) === 'string') { deferred.resolve('Hello, ' + name); } else { deferred.reject(name + 'は文字列ではありません。'); } }, 1000); return deferred.promise; } var r = document.getElementById('result'); var promise = asyncHello('sato'); promise.then( function(msg) { r.innerHTML += msg; }, function(msg) { r.innerHTML += msg; }, function(msg) { r.innerHTML += msg + '<br>'; } ); });
asyncHelloを2回使用する場合
var app = angular.module('app', []); app.controller('Ctrl', function($q, $timeout) { function asyncHello(name) { var deferred = $q.defer(); $timeout(function() { deferred.notify(name + 'を受け取りました。'); if(typeof(name) === 'string') { deferred.resolve('Hello, ' + name); } else { deferred.reject(name + 'は文字列ではありません。'); } }, 1000); return deferred.promise; } var r = document.getElementById('result'); var p1 = asyncHello('sato'); var p2 = asyncHello(326); var successCallback = function(msg) { r.innerHTML += msg + '<br>'; }; var errorCallback = function(msg) { r.innerHTML += msg + '<br>'; }; var notifyCallback = function(msg) { r.innerHTML += msg + '<br>'; }; p1.then(successCallback, errorCallback, notifyCallback); p2.then(successCallback, errorCallback, notifyCallback); });
promise.catch(errorCallback)
promise.then(null, errorCallback)と同じ。
$q.all()ですべての処理を監視
$q.all()を使用すればすべての処理が完了した後の処理を実行できる。
var app = angular.module('app', []); app.controller('Ctrl', function($q, $timeout) { function asyncHello(name) { var deferred = $q.defer(); $timeout(function() { deferred.notify(name + 'を受け取りました。'); if(typeof(name) === 'string') { deferred.resolve('Hello, ' + name); } else { deferred.reject(name + 'は文字列ではありません。'); } }, 1000); return deferred.promise; } var r = document.getElementById('result'); var p1 = asyncHello('sato'); var p2 = asyncHello(326); var successCallback = function(msg) { r.innerHTML += msg + '<br>'; }; var errorCallback = function(msg) { r.innerHTML += msg + '<br>'; }; var notifyCallback = function(msg) { r.innerHTML += msg + '<br>'; }; var p1End = p1.then(successCallback, errorCallback, notifyCallback); var p2End = p2.then(successCallback, errorCallback, notifyCallback); $q.all([p1End, p2End]).then( function() { r.innerHTML += 'すべての処理が完了しました。'; } ); });
thenのあとに実行するfinally
then().finally(finallyCallback())でthen実行後の処理を追加できる
var finallyCallback = function(msg) { r.innerHTML += 'thenの処理が完了しました。<br>'; }; var p1End = p1 .then(successCallback, errorCallback, notifyCallback) .finally(finallyCallback);