平常不怎么用promise,一是业务用不到,二是平常不用,看过了也就忘了,最近碰到这么三个异步操作,需要每一个都需要上一次返回。
- angularJS的回调是在
q
的
服
务
里
,
通
过
q的服务里,通过
q的服务里,通过q.defer()调用的deferred对象,代表一个将来要完成的任务,它有3个方法1个属性,
- resolve(value):根据value以解决派生的promise。相当于同意进行下一个函数,代表这个将来的任务已经执行完毕,并且结果是yes。返回的结果是一个promise。
- reject(reason):根据reason以拒绝派生的promise。这相当通过 $q.reject构造的rejection 对象来解决。
- notify(value):在 promise 被执行的过程中提供状态更新情况。这可能会被多次调用,在promise是被解决还是被拒绝之前。
- promise:承诺,与这个延迟相关的承诺对象。
简单来讲,一个是yes,一个是no,一个是status。还有一个用作返回结果。另外它还有另外的方法:when()和all(),文章的最后可能会提一下
- promise有三个方法分别是then,catch,和finally
- 我们用then(successCallback,errorCallback,notifyCallback)写后续的回调。
- catch可以捕捉err,类似then(null,errorCallback)
- finally无论结果如果必定会执行
调用实例:
var initNodeGroup = function () {
var def = $q.defer(); //定义一个deferred对象,代表一个将来要完成的任务。
bravoApi.node_group("?page=1&per_page=9999", {method: 'GET'}, function (res) {
//resolve用来跟下一步说yes,并且传递下一步需要依赖的参数,参数可以传递到then(fn(参数))中在下一个异步中(或非异步)中使用。
def.resolve(taskNodeGroups);
});
return def.promise; 返回promise对象,让下一个异步操作获得deferred的操作结果,是yes或者no,以此判断下一步是否执行。
};
//如上是一个promise链中的一环, 以此为例,我们可以一直加长这个链条。
//方法是fn().then().then().then().catch().finally();
initNodeGroup() //调用上面的参数返回值是def.promise所以,可以直接调用then()
//第一个then
.then(function (taskNodeGroups) {
var def = $q.defer(); //1
bravoApi.node_group("/" + taskNodeGroups[k].id, {method: 'GET'}, function (res) {
def.resolve($scope.task.node_id); //2
})
return def.promise; //3
})
//如果大家只是想使用一下,那么记住这3步就可以了,前提是记得在你的服务中注入$q.
//第二个then
.then(function (data) {
bravoApi.node_network($scope.task.node_id, function(res) {
//
});
})
我们上面说了,$q还有另外两个方法,when(),和all()
- when()我们可以理解为和resolve一样,只不过resolve更加和ES6保持一致。
- all()的使用背景是,当我们的下一步操作,需要两个异步操作全部完成后才能执行,例如,班车需要接A和B之后才能开车,所以我们需要等A()和B()两个异步同时执行完,才能进行下一步。返回的是promise的集合
调用例子:
var defA = $q.defer();
var defB = $q.defer();
setTimeOut(funciton(){
defA.reseolve('A');
},100)
setTimeOut(funciton(){
defB.reseolve('B');
},100)
var allQ = $q.all([
defA.promise,
defB.promise
])
allQ.then(funciton(res){
res[0]//A的结果
res[1]//B的结果
})
如果有多个请求就以此加入all的数组即可,这样必须集合中所有结果都是yes才会进行回调。