【问题标题】:Angular Promise Response CheckingAngular Promise 响应检查
【发布时间】:2015-11-11 23:47:06
【问题描述】:

我正在 Angular 中进行一些 http 调用,并在发生错误时尝试调用不同的服务函数。但是,无论我原来的服务调用函数返回如何,它返回的承诺始终是“未定义的”。这是一些给出上下文的代码:

  srvc.sendApplicantsToSR = function (applicant) {
    var applicantURL = {snip};

var promise = $http({
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    method: 'POST',
    url: applicantURL,
    data: applicant
})
  .success(function (data) {
    return data;
  })
  .error(function (error) {
    return [];
  });

  return promise;
  };

然后,在控制器中:

for (var applicant in $scope.applicants) {
            $scope.sendATSError($scope.sendApplicantsToSR($scope.applicants[applicant]), applicant);
       }

$scope.sendATSError = function (errorCheck, applicantNumber) {
      if (angular.isUndefined(errorCheck)) {
      console.log(errorCheck);
        AtsintegrationsService.applicantErrorHandling($scope.applicants[applicantNumber].dataset.atsApplicantID);
      }
    };

但是,它总是发送错误,因为每个响应都是未定义的。如何正确区分两个退货?谢谢!

【问题讨论】:

  • 试试 promise = $http(...);承诺.成功(...);回报承诺;
  • 您没有提供所有相关代码。第一个 sn-p 包含 srvc.sendApplicantsToSR,第二个是 $scope.sendApplicantsToSR。并且 angular.isUndefined 对于承诺来说总是错误的。 @hally9k Promises 不是那样工作的。
  • 所以 $http 不返回承诺是你在说什么?请解释您所说的“承诺不会那样工作”是什么意思。
  • 糟糕,抱歉@estus,我似乎粘贴了错误的 srvc 代码,但 errorHandling 与我提供的非常相似。 :) 只是一个不同的 URL,不需要那个标题。
  • Imcphers,您似乎对HTTP调用返回的data不感兴趣,只对调用是否成功感兴趣。我说的对吗?

标签: javascript angularjs promise


【解决方案1】:

angular documentation,示例代码是

$http({
  method: 'GET',
  url: '/someUrl'
}).then(function successCallback(response) {
    // this callback will be called asynchronously
    // when the response is available
  }, function errorCallback(response) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });

基于此 - 你的第一个代码 sn-p 应该是

 srvc.sendApplicantsToSR = function(applicant) {
     var applicantURL = {
         snip
     };

     return $http({
         headers: {
             'Content-Type': 'application/x-www-form-urlencoded'
         },
         method: 'POST',
         url: applicantURL,
         data: applicant
     });
 };

【讨论】:

  • 我使用文档返回了一个承诺 - 不确定 .success/.error 是什么,因为 angularjs 文档中没有记录
  • 好的!我明天会试试这个并回复你,但我认为这是有道理的。谢谢!
  • success/errordeprecated。与then 不同,它们确实返回一个新的承诺,这会破坏链接并导致混乱(如this question所示)。
【解决方案2】:

正如其他人所说,$http 的 .success().error() 已弃用,取而代之的是 .then()

但是您实际上不需要将.then() 链接到.sendApplicantsToSR(),因为您不需要(永远)处理成功交付的data 或处理(此时)不成功的错误。

$scope.sendApplicantsToSR = function (applicant) {
    var applicantURL = {snip};
    return $http({
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        method: 'POST',
        url: applicantURL,
        data: applicant
    });
};

现在,在调用者中(您在for 循环中的代码行),返回了一个promise(不是数据),并且该promise 将在解决时沿着其成功路径或它的错误路径。这些路径上发生的确切情况完全取决于您在一个或多个链接的 .thens 中编写的回调函数。

所以你需要写的是问题内容的一种由内而外的版本——外部是$scope.sendApplicantsToSR(),内部是$scope.sendATSError()——并与.then()链接在一起。

for (var prop in $scope.applicants) {
    var applicant = $scope.applicants[prop];
    $scope.sendApplicantsToSR(applicant).then(null, $scope.sendATSError.bind(null, applicant));
}
// Above, `null` means do nothing on success, and 
// `function(e) {...}` causes the error to be handled appropriately. 
// This is the branching you seek!!

通过传递错误处理程序applicant$scope.sendATSError() 将简化为:

$scope.sendATSError = function (applicant) {
    return AtsintegrationsService.applicantErrorHandling(applicant.dataset.atsApplicantID); // `return` is potentially important.
};

您可能想知道的唯一另一件事是所有承诺何时都已解决,但最好在另一个问题中解决。

【讨论】:

  • 您好,Roamer - 感谢您提供非常详细的回复。我正在尝试实现此解决方案,但我收到一个编译错误“[不要在循环中创建函数。]”显然这个错误是由 Play 抛出的,因为这是一个 Play 应用程序。你觉得我能做些什么呢?
  • 我显然只是通过将函数移到控制器中的循环之外来修复它。所以谢谢你的帮助漫游者! :)
  • 我犯了一个愚蠢的错误并编辑了代码。 applicant 需要绑定,否则applicant 的最终值将在每次调用错误处理程序时使用。
  • 将函数移出循环将修复编译错误,但不能修复我的“最终值”错误。
  • 由于异步性,for 循环将在错误处理程序被调用之前完成。基本问题解释here
【解决方案3】:

您应该返回您的承诺,由控制器自己处理。

简化:

.factory('myFactory', function() {
    return $http.post(...);
})
.controller('ctrl', function(){
    myFactory()
        .success(function(data){
             // this is your data
        })
})

工作示例:

angular.module('myApp',[])
.factory('myName', function($q, $timeout) {
    return function() {
        var deferred = $q.defer();
        $timeout(function() {
            deferred.resolve('Foo');
        }, 2000);
        return deferred.promise;
    }
})
.controller('ctrl', function($scope, myName) {
    $scope.greeting = 'Waiting info.';
    myName().then(function(data) {
       	$scope.greeting = 'Hello '+data+'!';
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="ctrl">
    {{greeting}}!
</div>

【讨论】:

  • 仅供参考,$http 承诺中的 successerror 方法现已弃用
  • 是的。使用 .then(..) 是正确的形式,就像 $q 承诺模式一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 2017-07-10
  • 2023-03-08
相关资源
最近更新 更多