如何从AngularJS中返回Promise的服务获取值

时间:2015-12-21 20:26:25

标签: angularjs

我正在尝试在控制器中调用服务方法。这是我的代码。 ROAService.js:

return{
    loadROAValues:function(userId,roaId){
        var params=JSON.stringify({userId:userId,roaId:roaId});
        var promise =$http.post(url+'/'+'getROAItems',params).success(function(data)   {  
            roaDetails = data;
            $log.debug("values in service class");
            $log.debug("values in ROA");
            $log.debug(roaDetails.id);
            return roaDetails
        })
        .error(function(data){
        roaDetails = 'error';
        return roaDetails;
        });
        return promise;
    }
}

在控制器ROA控制器中:

$scope.getCurrentROA = function(roaObj){
    currentROA = ROAService.loadROAValues($scope.getMemberId(),roaObj.id).then(function(response) {
       console.log(response);
    }).catch(function(response) {
       console.log("failure", response);
    });
    $log.debug("ROA id in controller class is:"+currentROA.id);
};

我得到以下输出:

ROA id in controller class is :undefined
    values in service class
    values in ROA
    386. 

来自控制器的ROA id在服务呼叫完成之前打印。它可能是竞争条件。如何保持控制器等到承诺返回?如何解决这种竞争状况?

1 个答案:

答案 0 :(得分:0)

  

如何保持控制器等到承诺返回?

代码存在两个问题。

  • 服务工厂功能正在.success方法中返回数据,但.success方法会忽略返回值

  • 控制器需要返回数据,但服务功能会返回承诺而不是数据。

另一个可能的问题是代码在定义服务工厂时定义服务类。很难从问题中判断出是否是这种情况,所以在我的例子中我会明确说明。

服务工厂

angular.module("myApp",[]);

angular.module("myApp").factory("ROAService", function($http) {
    function loadROAValues(userId,roaId){
        var params = JSON.stringify({userId:userId,roaId:roaId});

        var promise = $http.post(url+'/'+'getROAItems',params);

        //chain from .then method
        promise.then( function(response) {  
            var roaDetails = response.data;
            $log.debug("values in service class");
            $log.debug("values in ROA");
            $log.debug(roaDetails.id);
            //return data for chaining
            return roaDetails;
        //process error in .catch method
        }).catch( function(error){
            var roaDetails = 'error:' + error.status;
            //throw errors for chaining
            throw roaDetails;
        });
        //return promise for chaining
        return promise;
    };
    //return service function from factory
    return { loadROAValues: loadROAValues };
});

除了.success.error方法忽略返回值并返回旧承诺的问题之外,这些方法弃用即可。有关详细信息,请参阅AngularJS $http Service API Reference -- deprecation notice

控制器

angular.module("myApp").controller("myController",
    ['$scope', 'ROAService', function ($scope, ROAService) {
        //function returns a promise
        $scope.getCurrentROA = function(memberId, roaObj){
            //service function returns promise
            var promiseFromROA = 
                ROAService.loadROAValues(memberId, roaObj.id);
            //chain from promise
            promiseFromROA.then( function(roaDetails) {
                //$q service waits for promise to resolve
                //get values here
                $log.debug("ROA id is:"+roaDetails.id);
                //return for further chaining
                return roaDetails;
            }).catch ( function (error) {
                //process chained error
                console.log("failure: " + error);
                //throw for further chaining
                throw error;
            });
            //return promise for further chaining
            return promiseFromROA;
        };
    }]
);

功能编程的经验法则是始终返回。通过返回链接来利用承诺的力量。

有关链接的更多信息,请参阅AngularJS $q Service API Reference -- chaining promises