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 调用过程出现的错误
    
});


回到顶部