<!-- 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);
});