angular.js 下使用 $q 创建一个promise 链式调用
angular.js 下使用$q 创建一个 promose 链式调用.
我们在前几天分享了一篇,关于javascript中 promose 规范的博客 (点击查看)
现在很多很多的开源javascript库 实现了 promise 规范
大名鼎鼎的npm 包 Q
github地址: https://github.com/kriskowal/q
相仿的在 angular.js 下 $q 是一个小型轻量级的 promise 实现.作者据说是$q是从Kris Kowal的Q中获得灵感从而产生的一个promise/deffered实现
我们如何使用$q 定义一个 promise .
var getPersonList = function getPersonList() { var deferred = $q.defer(); //这里要经过一个一步请求拿到人员列表,也许很快,也许很久,但是是未知的 //这是我们一定知道大不了2种结果(成功,失败) //如果成功 deferred.resolve(person_list); //person_list是上面异步方法返回来的,我这里省略不写了 //如果失败 deferred.reject('get person list failure'); //这时我们已经包装好了一个 promise 返回给调用方 return deferred.promise; }
上面就是通过 $q 实现的一个promise 调用.
有的人可能迷糊了,如果我没有异步调用,该怎么写一个promise ,这时可能有人过来拍砖,没有异步还写个 promise 干毛毛啊?
其实开发中有时我们确实会遇到这种需求.
比如:
我要获取一个当前登录用户的详细信息,这个接口使用方希望提供一个统一的 promise 调用.下面我来模拟实现
var user_info=null; var userLogin=function userLogin(callback){ //调用数据层某个方法得到person对象,此方法也是返回promise 模拟如下:输入参数都省略了,直接就得到登录对象了,哈哈 DBhelper.userLogin().then(function(user){ user_info=user; callback(null,user_info); }); } //下面就是我们要定义的promise方法. var getCurrentUserDetail=function getCurrentUserDetail(){ var deferred = $q.defer(); //如果 user_info 有值,我们直接返回,如果没有就调用上面的方法获取 if(user_info){ //直接返回,很明显不符合接口规范,调用方希望统一用 promise 规范. //所以这里我们就需要把这个现成的返回值包装在promise 对象.如下 deferred.resolve(user_info); }else{ userLogin(function(user_info){ //这里出现上面代码的一幕,返回值2种情况,(成功,失败) //成功 deferred.resolve(user_info); //失败 deferred.reject('get current person failure'); //返回 promise 对象 return deferred.promise; }); } }
上面就是把已经有的现成值包装到 promise 对象中,也有异步回调模式包装成了promise 回调.这样接口就统一了.
下面模拟调用接口的时候:
getCurrentUserDetail().then(function(user_info){ //user_info 就是我们拿到的当前登录用户 }).catch(function(err){ //catch 函数会捕捉promise 调用过程出现的错误 });