<!-- lang: js -->
var deferred = $q.defer();
var promise = deferred.promise;
promise.then(function success(data) {//成功
console.log(data);
},
function error(error) {//錯誤
console.error(error);
},
function notification(notification) {//狀態
console.info(notification);
}));
var progress = 0;
var interval = $interval(function() {
if (progress >= 100) {
$interval.cancel(interval);
deferred.resolve('All done!');//成功消息
}
progress += 10;
deferred.notify(progress + '%...'); //狀態消息
}, 100)
不用 then() 的第二個參數,還有另外一種選擇,你可以用鏈式的 catch(),在 promise 鏈中發生異常的時候它會被調用(可能在很多鏈之后)。
<script type="text/javascript">
var myAppModule = angular.module("myApp",[]);
myAppModule.controller("myctrl",["$scope","$q",function($scope, $ q ){
$scope.test = 1;//這個只是用來測試angularjs是否正常的,沒其他的作用
var defer1 = $q.defer();
var promise1 = defer1.promise;
promise1
.then(function(value){
console.log("in promise1 ---- success");
console.log(value);
},function(value){
console.log("in promise1 ---- error");
console.log(value);
},function(value){
console.log("in promise1 ---- notify");
console.log(value);
})
.catch(function(e){
console.log("in promise1 ---- catch");
console.log(e);
})
.finally(function(value){
console.log('in promise1 ---- finally');
console.log(value);
});
defer1.resolve("hello");
// defer1.reject("sorry,reject");
}]);
</script>
鏈式處理
var deferred = $q.defer();
var promise = deferred.promise;
promise
.then(function(val) {
console.log(val);
return 'B';
})
.then(function(val) {
console.log(val);
return 'C'
})
.then(function(val) {
console.log(val);
});
deferred.resolve('A');
這會在控制臺輸出以下結果:
<!-- lang: js -->
A
B
C
reject,會調用catch,不調用then,在鏈式調用的時候使用
$q.reject("instant reject") .catch(function (err) { console.log(err); });
我還提到了** $q.all(),允許你等待并行的 promise 處理,當所有的 promise 都被處理結束之后,調用共同的回調。在 Angular 中,這個方法有兩種調用方式: 以 Array 方式或 Object **方式。Array 方式接收多個 promise ,然后在調用 .then() 的時候使用一個數據結果對象,在結果對象里面包含了所有的 promise 結果,按照輸入數組的順序排列:
<!-- lang: js -->
$q.all([promiseOne, promiseTwo, promiseThree])
.then(function(results) {
console.log(results[0], results[1], results[2]);
});
第二種方式是接收一個 promise 集合對象,允許你給每個 promise 一個別名,在回調函數中可以使用它們(有更好的可讀性):
<!-- lang: js -->
$q.all({ first: promiseOne, second: promiseTwo, third: promiseThree })
.then(function(results) {
console.log(results.first, results.second, results.third);
});
我建議使用數組表示法,如果你只是希望可以批處理結果,就是說,如果你把所有的結果都平等處理。而以對象方式來處理,則更適合需要自注釋代碼的時候。
另一個有用的方法是** $q.when()**,如果你想通過一個普通變量創建一個 promise ,或者你不清楚你要處理的對象是不是 promise 時非常有用。
<!-- lang: js -->
$q.when('foo')
.then(function(bar) {
console.log(bar);
});
$q.when(aPromise)
.then(function(baz) {
console.log(baz);
});
$q.when(valueOrPromise)
.then(function(boz) {
// well you get the idea.
})
$q.when() 在諸如服務中的緩存這種情況也很好用:
接收第一個參數為一個任意值或者是一個promise對象,其他3個同promise的then方法,返回值為一個promise對象。第一個參數若不是promise對象則直接運行success回調且消息為這個對象,若為promise那么返回的promise其實就是對這個promise類型的參數的一個包裝而已,被傳入的這個promise對應的defer發送的消息,會被我們when函數返回的promise對象所接收到。
var defer1 = $q.defer();
var promise1 = defer1.promise;
var promise2 = $q.when(promise1, function(num) {
console.log("s" + num);
}, function() {
console.log("e");
});
defer1.reject(1);
運行結果:
e
<!-- lang: js -->
angular.module('myApp').service('MyService', function($q, MyResource) {
var cachedSomething;
this.getSomething = function() {
if (cachedSomething) {
return $q.when(cachedSomething);
}
// on first call, return the result of MyResource.get()
// note that 'then()' is chainable / returns a promise,
// so we can return that instead of a separate promise object
return MyResource.get().$promise
.then(function(something) {
cachedSomething = something
});
};
});
然后可以這樣調用它:
<!-- lang: js -->
MyService.getSomething()
.then(function(something) {
console.log(something);
});