以前只知道简单的ajax请求,也就是请求回调的模式,看了angularJs中大规模的promise,尤其是$q和defer,promise以及怎么resolve,reject非常疑惑,在搜集了大量的关于promise的资料后大致整理出他们的用途。其实引入promise主要还是为了解决以前的回调过于深入的问题,也就是ajax依赖上次请求返回成功后在执行;
<pre name="code" class="html"><pre name="code" class="javascript"><span style="font-size:18px;">functionA(arg1,arg2,function(){ functionB(arg1,function(){ functionC(arg1,function(){ xxxx.... }) }) })</span>
也就是传说中的金字塔回调的问题。夏天要来了,你一定希望看见angularJS中提供的更加清爽的方式;
<span style="font-size:18px;">Promise.then(succFuntion,failFuntion) .then(succFuntion,failFountion) .catch() .finally()</span>
这种模式,是不是宛若一阵清风来袭,特别清爽,then就是然后,然后干嘛,对了就是succFuntion,错了就执行failFunction,到这里还是很清晰的,也没有问题。但是怎么用呢?怎么触发使用?
在angularJS中主要是$q和defer,promise的使用:
一般我们使用异步请求的话就使用$q服务,那怎么做呢?
首先来看一个demo:
var defer = $q.defer(); var promise = defer.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');
这里只有一个函数,就是上面好了then我们要干啥。
defer是一个延迟对象,通过$q.defer来获取;
它有以下方法:
resolve(value):向promise对象异步执行体发送消息告诉他我已经成功完成任务,value即为发送的消息。
reject(value):向promise对象异步执行体发送消息告诉他我已经不可能完成这个任务了,value即为发送的消息。
notify(value):向promise对象异步执行体发送消息告诉他我现在任务完成的情况,value即为发送的消息。
他还有一个属性,就是promise,也就是这个对象的承诺(promise)对象;
defer主要是用来发消息的,也就是来开启这个过程,虽然它被写在了最后面==!,如果是我们写了defer.reject(),那我们的promise就要对应的执行第二个回调函数,failFunction,这里没有写出来failFuntion,demo中有;
其实传递应该是这样的
promise对象可以通过defer.promise获取,下面是promise对象的方法:
then(successCallback,errorCallback,notifyCallback):参数为不同消息下的不同回调函数,defer发送不同的消息,resolve发成功的消息,执行successCallback,reject发另一种执行errorCallback等等,一般我们用resolve代表成功的操作,reject代表失败的操作,最开始我的迷惑是我调用了resolve不会触发errorCallBack吗,我一直以为调用一个就行了,其实这个地方是区分的,你发的消息(resolve和reject)不一样,函数执行的回调才回不一样。消息作为这些回调函数的参数传递。then的返回值也是为一个promise,这样我们就可以再次添加then了。对象为支持链式调用而存在。当第一个defer对象发送消息后,后面的promise对应的defer对象也会发送消息,但是发送的消息不一样,不管第一个defer对象发送的是reject还是resolve,第二个及其以后的都是发送的resolve,因为第一个个不管执行什么,都有返回吗,后面的不需要考虑前面调用是什么,只需要根据前面的结果来判断就行了。这样消息是可传递的。
finally(callback):相当于then(callback,callback)的缩写,这个finally中的方法不接受参数,可以将defer发送的消息和消息类型成功传递到下一个then中,就是不管怎样都要执行回调。
最后一个问题是$q.when,这个我还没有真正用到,后面会结合实际使用来描述,目前已有的信息很模糊,大概都是说使用$q的when方法可以直接生成promise对象,比如:
varpromise=$q.when(1,function(num){
console.log("s"+num);
},function(){
console.log("e");
});
意思是说吧这样一坨东西封装成一个promise对象,这样以来,我们使用promise的时候又会开始promise.then()这样的使用,也就是说,promise之后要干嘛。。。这个感觉有一点等待的意味,就是等待when中的事情完成的时候在执行then;当when("do some thing"),当when中干什么的时候,然后我们就可以开始then....
over