AngularJS的承诺在没有等待异步响应的情况下被拒绝(它应该会被解析)

AngularJS Promise being rejected without waiting for async response (it should resolve)

本文关键字:拒绝 情况下 承诺 等待 响应 异步 AngularJS      更新时间:2023-09-26

在我的场景中,当访问者第一次导航到一个页面(或路由)时,他们应该匿名身份验证(我使用的是Firebase)。上下文;之后,访问者可能会在登录后迁移他们的匿名会话,例如使用Facebook。

如果匿名身份验证由于某种原因失败,它们将被重定向到错误页面(路由)——少数不需要任何身份验证的页面之一。

我正在使用promise to:

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

问题:

承诺总是在访问者第一次导航到需要身份验证的页面(路由)时被拒绝,即使访问者已经匿名身份验证成功(在上面的步骤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;
      };
    }
  });
}]);

deferred.reject不作为错误函数传递给then,每次都调用

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

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

您应该知道上面的代码通常被称为延迟反模式。最好使用已有的承诺,而不是使用defer()创建一个新的承诺。