angularjs $q服务学习

文章参考

http://www.jb51.net/article/61638.htm

http://www.cnblogs.com/xing901022/p/4928147.html

Promise

Promise是一种模式,以同步操作的流程形式来操作异步事件,避免了层层嵌套,可以链式操作异步事件

我们知道,在编写javascript异步代码时,callback是最最简单的机制,可是用这种机制的话必须牺牲控制流、异常处理和函数语义化为代价,甚至会让我们掉进出现callback大坑,而promise解决了这个问题。

ES6中Promise、angularJS内置的AngularJS内置Q,以及when采用的都是Promises/A规范,如下:

每个任务都有三种状态:未完成(pending)、完成(fulfilled)、失败(rejected)。

1.pending状态:可以过渡到履行或拒绝状态。

2.fulfilled状态:不能变为其他任何状态,而且状态不能改变,必须有value值。

3.rejected状态:不能变为其他任何状态,而且状态不能改变,必须有reason。

状态的转移是一次性的,状态一旦变成fulfilled(已完成)或者failed(失败/拒绝),就不能再变了。

$q服务

q服务是AngularJS中自己封装实现的一种Promise实现,相对与Kris Kwal's Q要轻量级的多。

先介绍一下$q常用的几个方法:

defer() 创建一个deferred对象,这个对象可以执行几个常用的方法,比如resolve,reject,notify等

all() 传入Promise的数组,批量执行,返回一个promise对象

when() 传入一个不确定的参数,如果符合Promise标准,就返回一个promise对象

案例

function okToGreet(name){
    return name === 'Robin Hood';
}

function asyncGreet(name) {
    var deferred = $q.defer();

    setTimeout(function() {
        // 因为这个异步函数fn在未来的异步执行,我们把代码包装到 $apply 调用中,一边正确的观察到 model 的改变
        $scope.$apply(function() {
		//执行promise.then的第三个参数(notifyCallback)方法
            deferred.notify('About to greet ' + name + '.');

            if (okToGreet(name)) {
			//执行promise.then的第一个参数(successCallback)方法
                deferred.resolve('Hello, ' + name + '!');
            } else {
			//执行promise.then的第二个参数(errorCallback)方法
                deferred.reject('Greeting ' + name + ' is not allowed.');
            }
        });
    }, 1000);

    return deferred.promise;
}

var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
    alert('Success: ' + greeting);
}, function(reason) {
    alert('Failed: ' + reason);
}, function(update) {
    alert('Got notification: ' + update);
});

Promise API

当创建 deferred 实例时会创建一个新的 promise 对象,并可以通过 deferred.promise 得到该引用。

promise 对象的目的是在 deferred 任务完成时,允许感兴趣的部分取得其执行结果。

promise 对象的方法

then(successCallback,errorCallback,notifyCallback):参数为不同消息下的不同回调函数,defer发送不同的消息执行不同的回调函数,消息作为这些回调函数的参数传递。返回值为回一个promise对象为支持链式调用而存在。当第一个defer对象发送消息后,后面的promise对应的defer对象也会发送消息,但是发送的消息不一样,不管第一个defer对象发送的是reject还是resolve,第二个及其以后的都是发送的resolve,消息是可传递的。

catch(errorCallback):then(null,errorCallback)的缩写。

finally(callback):相当于then(callback,callback)的缩写,这个finally中的方法不接受参数,却可以将defer发送的消息和消息类型成功传递到下一个then中。


 下面是自己工作中写的例子——两个异步请求,如何按照顺序执行(异步请求同步处理)

/**
 * 进入页面的控制器 controller
 * */
angular.module("hkApp").controller("salesGoodsTop10Controller", ["$scope", "$state",'salesGoodsTop10Service', function ($scope, $state,salesGoodsTop10Service) {

    //第一步,获取前十的商品list
    var promise = salesGoodsTop10Service.getSalesGoodsStatisticsList();
    promise.then(function(returnData){
        $scope.lists = returnData.data;
        //第二步,获取商品的总数量,返回的是promise对象,作为第二个then的执行方法
        return  salesGoodsTop10Service.getGatherTotal();
    }).then(function(returnData){
            $scope.gatherTotal = returnData.data;
        });

    $scope.goBack = function(){
        window.history.back();
    };

}]);


/**
 * 向服务器发送请求的服务 service
 * */
angular.module("hkApp").factory("salesGoodsTop10Service",["$http","$q",function($http,$q){

    /**
     * 获取商品前10的商品
     * */
    var getSalesGoodsStatisticsList = function (){
        var deferred = $q.defer();
        var url = "/index.php/Admin/GatherGoods/gatherGoodsTop.html";
        var params = {
            "top":5
        };
        $http.post(url,params)
            .success(function(response, status, headers, config){
                if(response.status == 1){
                    deferred.resolve(response);
                }
            });
        return deferred.promise;
    };

    /**
     * 获取销售商品总数
     * */
    var getGatherTotal = function (){
        var deferred = $q.defer();
        var url = "/index.php/Admin/GatherGoods/gatherTotal.html";
        $http.post(url)
            .success(function(response, status, headers, config){
                if(response.status == 1){
                    deferred.resolve(response);
                }
            });
        return deferred.promise;
    };

    var resultJson = {
        "getSalesGoodsStatisticsList":getSalesGoodsStatisticsList,
        "getGatherTotal":getGatherTotal
    };

    return resultJson;
}]);

  

猜你喜欢

转载自hbiao68.iteye.com/blog/2300956
今日推荐