このエントリはAngular JS Advent Calendarの投稿です。
#Promise使ってますか?
Promiseは非同期をうまくやってくれます。
Promise インターフェースは作成時点では分からなくてもよい値へのプロキシです。プロミスを用いることで、非同期アクションの成功や失敗に対するハンドラを関連付けることができます。これにより、非同期メソッドは、最終的な値を返すのではなく、未来のある時点で値を持つプロミスを返すことで、同期メソッドと同じように値を返すことができるようになります。
プロミスは何らかの値をもって成功、もしくは何らかの理由をもって失敗となることができます。そのどちらとなっても、then メソッドによって関連付けられたハンドラが呼ばれます。
Promise.prototype.then メソッドと Promise.prototype.catch メソッドはプロミス値を返すので、メソッドチェインによって合成することができます。
とは言え、サービスを作る際にお世話になっていると思います。
var service = angular.module("customServices", []);
service.factory("customService", ["$q", "$timeout", function($q, $timeout){
return {
merry: function(){
var d = $q.defer();
$timeout(function(){
d.resolve("メリー");
}, 1000);
return d.promise;
},
christmas: function(){
var d = $q.defer();
$timeout(function(){
d.resolve("クリスマス");
}, 1000);
return d.promise;
}
};
}]);
var app = angular.module("myApp", ["customServices"]);
app.controller("myController", ["$q", "customService", function(customService){
$q.all([customService.merry(), customService.christmas()]).then(function(strs){
var merry = strs[0];
var christmas = strs[1];
alert(merry+"・"+christmas);
});
}]);
このように複数の非同期処理を一つにまとめたりするのに大変重宝します。
しかし、たまには1つだけ処理が欲しい場合があります。
promiseを利用しているとなんとなくコールバックがダサく感じてしまいます。
しかし、1つだけの場合はいままで通りコールバックのほうが使い慣れていると思いますのでコールバックもあったほうがいいと考えています。
var service = angular.module("customServices", []);
service.factory("customService", ["$q", "$timeout", function($q, $timeout){
return {
merry: function(callback){
var d = $q.defer();
$timeout(function(){
d.resolve("メリー");
if(typeof callback == "function"){
callback("メリー");
}
}, 1000);
return d.promise;
},
christmas: function(callback){
var d = $q.defer();
$timeout(function(){
d.resolve("クリスマス");
if(typeof callback == "function"){
callback("クリスマス");
}
}, 1000);
return d.promise;
}
};
}]);
2つ書くのは面倒ではありますが、serviceを作るに当たり、返りの選択肢は複数あったほうがいいと考えています。