AngularJS Promise被拒绝而不等待异步响应(它应该解决)

时间:2015-09-07 10:12:17

标签: javascript angularjs firebase promise angular-routing

在我的场景中,当访问者第一次导航到页面(或路线)时,他们应该进行匿名身份验证(我使用的是Firebase)。对于背景;稍后访问者可以在登录后使用Facebook迁移他们的匿名会话。

如果匿名身份验证由于某种原因失败,则会将其重定向到错误页面(路由) - 几个不需要任何身份验证的页面之一。

我正在使用承诺:

  1. 检查访问者是否已经过身份验证
  2. 如果不是,请尝试并匿名验证他们
  3. 如果成功通过身份验证,请解决承诺(和路由)
  4. 如果由于某种原因验证失败,请拒绝承诺
  5. 问题:

    当访问者第一次导航到需要身份验证的页面(路由)时,即使访问者已成功进行匿名身份验证(在上面的步骤2中),该承诺似乎总是被拒绝;为什么会发生这种情况?

    下面我已经包含了我的代码,并添加了注释以突出显示导致问题的部分。

    感谢您对此的帮助,我们将不胜感激!

    var app = angular.module('vo2App', ['firebase', 'ngCookies', 'ngRoute']);
    
    app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
    
      $routeProvider
      .when('/', {
        controller: 'HomeCtrl',
        templateUrl: '/views/home.html'
      })
      .when('/login', {
        controller: 'LoginCtrl',
        templateUrl: '/views/login.html'
      })
      .when('/oops', {
        controller: 'OopsCtrl',
        resolve: {
          currentAuth: function (){
            return null;
          }
        },
        templateUrl: '/views/oops.html'
      });
    }]);
    
    app.run(['$location', '$rootScope', 'Auth', 'ErrorMsg', function ($location, $rootScope, Auth, ErrorMsg) {
      $rootScope.$on('$routeChangeError', function (event, next, prev, error) {
        if (error === 'AUTH_REQUIRED') {
          ErrorMsg.add('Unauthorized');
          // TODO: Make all error messages constants
    
          $location.url('/oops');
        }
      });
    
      $rootScope.$on('$routeChangeStart', function (event, next, current) {
        if (! ('resolve' in next)) {
          next.resolve = {};
        }
    
        if (! ('currentAuth' in next.resolve)) {
          next.resolve.currentAuth = function ($q, Auth) {
            var deferred = $q.defer();
    
            Auth.$requireAuth().then(deferred.resolve, function () {
    
              /* ** The following line seems to be causing the problem ** */
    
              Auth.$authAnonymously().then(deferred.resolve, deferred.reject('AUTH_REQUIRED'));
            });
    
            return deferred.promise;
          };
        }
      });
    }]);
    

1 个答案:

答案 0 :(得分:3)

deferred.reject未作为错误函数传递给then,每次都会调用它。

Auth.$authAnonymously().then(deferred.resolve, deferred.reject('AUTH_REQUIRED'));

这就是为什么deferred.promise总是被拒绝的原因。

您应该知道上面的代码通常被称为deferred antipattern。最好使用现有的承诺,而不是使用defer()创建新的承诺。