AngularJS Promise 错误捕获

Posted

技术标签:

【中文标题】AngularJS Promise 错误捕获【英文标题】:AngularJS Promise error catching 【发布时间】:2014-11-25 07:52:22 【问题描述】:

有如下代码:

 angular.module('app.services', []).factory('authService', [
'SIGN_IN_ENDPOINT', 'SIGN_OUT_ENDPOINT', '$http', '$cookieStore', function(SIGN_IN_ENDPOINT, SIGN_OUT_ENDPOINT, $http, $cookieStore) 
  var auth;
  auth = ;
  auth.signIn = function(credentials) 
    return $http.post(SIGN_IN_ENDPOINT, 
      user: credentials
    ).then(function(response, status) 
       return $cookieStore.put('user', response.data);
    , function(error) 
       return console.log("Incorrect email/password");
    );
   ;
  return auth;
 

这是我的身份验证模块。现在我在控制器中有以下功能:

angular.module('app.admin.controllers', []).controller('SignInController', [
  '$scope', 'authService', '$state', function($scope, authService, $state) 
    $scope.buttonText = "Login";
    return $scope.login = function() 
      $scope.buttonText = "Logging in. . .";
      return authService.signIn($scope.credentials).then(function(response, status) 
        return $state.go('allPosts');
      , function(err) 
        $scope.invalidLogin = true;
        return $scope.buttonText = "Login";
      );
   ;
 

问题:如果我输入了错误的电子邮件/密码,我正在等待 2 个错误回调 - 从第一个“then”到第二个,但我捕获了第一个错误回调(我可以看到控制台日志)和之后它执行成功回调! (返回 $state.go('allPosts'))。为什么?来自服务器的响应是 401 错误。

【问题讨论】:

【参考方案1】:

这样做的原因是,您在“app.services”中发现了错误,而不是将问题“冒泡”到更高层。

angular.module('app.services', []).factory('authService', [
'SIGN_IN_ENDPOINT', 'SIGN_OUT_ENDPOINT', '$http', '$cookieStore', function(SIGN_IN_ENDPOINT, SIGN_OUT_ENDPOINT, $http, $cookieStore) 
  var auth;
  auth = ;
  auth.signIn = function(credentials) 
    return $http.post(SIGN_IN_ENDPOINT, 
      user: credentials
    ).then(function(response, status) 
       return $cookieStore.put('user', response.data);
    , function(error) 
       console.log("Incorrect email/password");
       return $q.reject();  //here is the important one.
    );
   ;
  return auth;
 

或者完全错过错误处理程序。

auth.signIn = function(credentials) 
        return $http.post(SIGN_IN_ENDPOINT, 
          user: credentials
        ).then(function(response, status) 
           return $cookieStore.put('user', response.data);
        );
       ;

如果你捕捉到错误并在错误中返回一个值,那么下面的承诺不知道发生的错误。

【讨论】:

好的,谢谢。但是为什么我不需要将成功“冒泡”到更高的水平呢?我应该只为错误而做吗?谢谢。 通过在其中一个回调中返回一个值,您基本上成功了 TBH 关于 $q 的官方文档应该包含此信息,但我还没有找到它。我确实自己发现了它(艰难的方式)。 docs.angularjs.org/api/ng/service/$q【参考方案2】:

由于auth服务返回的是then函数返回的promise,所以在第一个错误回调中你需要返回rejectedpromise。

你可以这样做:

auth.signIn = function(credentials) 
    return $http.post(SIGN_IN_ENDPOINT, 
      user: credentials
    ).then(function(response, status) 
       return $cookieStore.put('user', response.data);
    , function(error)  
       console.log("Incorrect email/password");
       return $q.reject(error);   // return a rejected promise;
    );
   ;

还记得将$q 注入到您的服务中,这样才能正常工作。

then 返回的 promise 使用成功和错误回调函数的返回值解析。 如果您进行标准回报,您将始终走上成功之路。 当您返回 $q.reject 时,您将返回一个最终被拒绝的承诺。请参阅 $q 上的 documentation。

您也可以从服务中的错误回调中抛出异常并获得相同的结果。

【讨论】:

为什么我不需要相同的 ($q.reject) 来进行成功回调? AngularJs 会自动完成吗?

以上是关于AngularJS Promise 错误捕获的主要内容,如果未能解决你的问题,请参考以下文章

使用 angularJS 和 Typescript 的 Promise

如何在angularjs中链接promise错误函数

等待点击 Promise 完成的 Angular 指令

用一级 try ... catch 捕获 JavaScript Promise 中的错误

未捕获的 Promise 错误:TypeError:成员不是函数

Promise 在应该捕获错误时解决