一:$q介绍
$q是angularjs 内置的一种服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常)。
二:defer介绍
defer的字面意思是延迟,$q.defer()可以创建一个deferred实例(延迟对象实例)。
deferred 实例旨在暴露派生的Promise 实例,被用来作为成功完成或未成功完成的信号,以及当前任务的状态。这听起来好复杂的样子,总结$q, defer, promise三者之间的关系如下所示。
var deferred = $q.defer();//通过$q服务注册一个延迟对象 deferred
var promise = deferred.promise;//通过deferred延迟对象,可以得到一个承诺promise,而promise会返回当前任务的完成结果
三:defer 的方法
1. deferred.resolve(value) 成功解决(resolve)了其派生的promise。参数value将来会被用作promise.then(successCallback(value){...}, errorCallback(reason){...}, notifyCallback(notify){...})中函数的参数。
2. deferred.reject(reason) 未成功解决其派生的promise。参数reason被用来说明未成功的原因。此时deferred实例的promise对象将会捕获一个任务未成功执行的错误,promise.catch(errorCallback(reason){...})。补充一点,promise.catch(errorCallback)实际上就是promise.then(null, errorCallback)的简写。
3. notify(value) 更新promise的执行状态(翻译的不好,原话是provides updates on the status of the promise's execution)
四:一个defer的应用的例子
这个例子主要是想实现一个input框输入名称文字,点击提交方法,带着名字这个参数触发调用服务。这个服务里面的函数主要做了一件事。就是判断这个参数的名字是不是叫‘zhangsan’,是的话,返回值;不是的话也返回值。
接下来就是这个例子:
1:页面view
2:controller
这个controller里面加载了$q ,okToGreet 和asyncGreet服务。并且调用了asyncGreet里面的ansyncG方法用来处理逻辑。最后打印结果。
3:service里面引用$q服务
4:一个名称验证的service
这个例子就大体上展示了$q的用法。当创建一个deferred实例时,promise实例也会被创建。通过deferred.promise就可以检索到deferred派生的promise。
promise的目的是允许外界访问deferred任务完成的结果。
return deferred.promise;相当于返回一个承诺,承诺你这个任务在给定的时间点上可能会完成,也可能完成不了。如果完成了那就相当于resolve, 如果未完成就相当于reject。
五:关于promise的方法
在controller当中,调用sevice里面的方法显示返回值的时候,注意到,我们用到了:
$q.when(asyncGreet.asyncG($scope.myname))
.then(function(result){......},function(reason){......})
.finally(function(){.........});
那,Promise就可以理解为一种对执行结果不确定的一种预先定义。
1:when() 传入一个不确定的参数,如果符合Promise标准,就返回一个promise对象。
2:.只要符合promise标准就执行then().就开始调用 成功/错误 回调函数。
3:catch(errorCallback) —— promise.then(null, errorCallback) 的快捷方式。这个我暂时还不太知道在哪用。
4:.finally 就是不管我调用什么东西,成功不成功,都要调用一下finally。用一个例子说就是:我让小明出去买饭,有西红柿盖饭就带西红柿盖饭,有麻辣烫就带麻辣烫。但是不管这俩有没有,最后都得给我买瓶饮料回来。
六:all( )方法
all()方法,可以把多个primise的数组合并成一个。当所有的promise执行成功后,会执行后面的回调。回调中的参数,是每个promise执行的结果。
当批量的执行某些方法时,就可以使用这个方法。例如:
这个例子最终会返回:
七:上面的例子稍微有些复杂,借用网上的一个简单例子,可以更好的了解$q;如下:
最终会返回:
很显然。执行了第一成功的then和最后的finally。
其实。当你实例化$q了以后,不管你去做了什么。最后子要把返回值给resolve(res..)出来,就可以通过$q的when.then....去调用。