Javascript 将作用域应用于服务中的promise.then()函数

Javascript 将作用域应用于服务中的promise.then()函数,javascript,angularjs,promise,Javascript,Angularjs,Promise,我是安格拉斯的新手 我正在从与Web服务通信的控制器调用服务。服务向控制器返回一个承诺。现在,我想将promise的success函数中可用的数据应用到$scope。我怎样才能做到这一点?我已经尝试对服务调用或promise success函数执行$scope.$apply(),但这只会给我带来错误 控制器: angular.module('home') .controller('HomeCtrl', ['$scope', 'myService', functio

我是安格拉斯的新手

我正在从与Web服务通信的控制器调用服务。服务向控制器返回一个承诺。现在,我想将promise的success函数中可用的数据应用到$scope。我怎样才能做到这一点?我已经尝试对服务调用或promise success函数执行$scope.$apply(),但这只会给我带来错误

控制器:

angular.module('home')
    .controller('HomeCtrl',
    ['$scope', 'myService',
        function ($scope, myService) {

            $scope.data = [];

            $scope.getData = function () {
                // this is triggered via btn click
                myService.getSomeData(reqData)
                    .then(
                    function success(res){
                        // apply res.data to $scope.data ?
                    },
                    function failure(err){
                       //error handling
                    }
                );
            }
        }]);
服务:

angular.module('myService')

    .factory('myService', ['$http', '$rootScope',
        function ($http, $rootScope) {
            return {

                generalWebServiceProxy: function (webserviceName, data, xml) {
                    // do some xml stuff, settings header etc

                    return $http({
                        method: 'POST',
                        url: URL,
                        headers: headers,
                        data: data
                    });
                },

                getSomeData: function (data) {
                    return this.generalWebServiceProxy('WSName', data, true).then(/* do something here and return data*/);
                }
            }
        }]);

提前谢谢

$http是一个承诺,在这里,您不会返回承诺并将其用作控制器中的承诺

修改服务:

angular.module('myService')

    .factory('myService', ['$http', '$rootScope',
        function ($http, $rootScope) {
            return {

                generalWebServiceProxy: function (webserviceName, data, xml) {
                    // do some xml stuff, settings header etc

                    return $http({
                        method: 'POST',
                        url: URL,
                        headers: headers,
                        data: data
                    });
                },

                getSomeData: function (data) {
                    return this.generalWebServiceProxy('WSName', data, true);
                }
            }
        }]);

并使控制器保持原样,并在成功块中更新$scope变量。

$http返回一个承诺,其中解析了服务器响应。该响应对象包含状态、数据、标题等内容。。等等

您的服务应该自行处理这些响应。因此,方法
setSomeData
解析为该数据。现在,它正在解析服务器响应,这对您的指令不是很有用

generalWebServiceProxy: function (webserviceName, data, xml) {
   // this method is return a promise
   return $http({...});
},

// this method uses "promise chaining"
getSomeData: function (data) {
     return this.generalWebServiceProxy(
     'WSName',
     data,
     true).then(function(response) {
         if(response.status == 200) {
            return response.data;
         }
         throw new Error("Unexpected response:"+response.status);
    });
}
在上面的代码中,我做了一个叫做承诺链接的事情。在这里,a的返回值会改变resolve值。因此,下一个promise-then调用将使用
response.data
作为参数

稍后在指令中,您可以使用服务返回的承诺作为常规承诺。它只解析为响应中的
数据

$scope.getData = function () {
    myService.getSomeData(reqData)
        .then(function success(data) {
            // ^^ data is actually the value `response.data` from the service
        });
}
错误处理呢? $http有两种错误。存在HTTP错误,如无法解析主机、连接失败或超时,然后是响应错误。例如内容丢失或找不到内容。其中一些可以通过promise failure回调来处理,还有一些是您不想要的成功响应

因此,在我的示例中,我将成功限制为HTTP 200响应。您可能需要检查返回的数据是否符合预期(例如,是否为数组?)


我发现使用HTTP拦截器处理错误更好。否则,您必须在使用该服务的每个指令中实现错误句柄。

您不知道我在.then()部分中返回了什么(因为我遗漏了它)。我一直认为,在承诺链上,返回值是异步还是同步并不重要。没关系-即使遗漏了服务上的.then函数,$scope在控制器上的success函数上也无法访问。未捕获引用错误:$未定义作用域(…)我的服务已在执行响应和错误处理。已经有很多承诺链正在发生。我只是简化了示例,因为这段代码超出了范围。你给出了一个非常详细的关于承诺链和错误处理的答案,这不是我问题的一部分。您说过“稍后在您的指令中,您可以使用服务返回的承诺作为常规承诺”,这是我的实际问题。如果我在控制器上执行$scope.data=关于成功的数据fn,我将获得未捕获的引用错误:$scope未定义(…)