2015-09-07 44 views
0

在我的場景中,當訪問者第一次瀏覽頁面(或路由)時,應該對其進行匿名身份驗證(我正在使用Firebase)。對於上下文;稍後訪問者可能會在他們登錄後,例如與Facebook之間遷移他們的匿名會話。AngularJS Promise在不等待異步響應的情況下被拒絕(應該解決)

如果由於某種原因匿名身份驗證失敗,它們將被重定向到錯誤頁面(路由) - 幾個不需要任何身份驗證的頁面之一。

我使用的承諾:

  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; 
     }; 
    } 
    }); 
}]); 

回答

3

deferred.reject不傳遞給then作爲誤差函數,它被稱爲每次。

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

這就是爲什麼deferred.promise總是被拒絕。

而且您應該知道上面的代碼通常被稱爲deferred antipattern。最好使用現有的承諾,而不是用defer()創建一個新的承諾。

+0

謝謝!我正要回答我自己的問題,現在我已經知道了,但你打敗了我,並添加了整潔的小提示! –

+0

的'rootChangeStart'表達可以是如'$ rootScope簡單$上( '$ routeChangeStart',功能(事件,接着,電流){ \t \t next.resolve = next.resolve || {};。 \t \t next.resolve.currentAuth = next.resolve.currentAuth || Auth。$ requireAuth.bind(Auth); \t});'。 '.bind(Auth)'可能不是必需的。 –