【问题标题】:AngularJS: how to stay in 'run' method until it finishesAngularJS:如何保持“运行”方法直到它完成
【发布时间】:2015-08-06 23:19:59
【问题描述】:

我有一个简单的场景 - 我希望使用拦截器初始化我的 http 调用,该拦截器将在标头中添加一个值(某种标记)。

问题是令牌也是通过 http 接收的(它应该是第一次调用),但我不知道如何让所有其他调用等待它完成,然后再发出自己的调用...

.factory('sessionData', function () {
    var currentToken = '[uninitialized-token]';
    return {
        getToken: function () {
            return currentToken;
        },
        setAuthData: function (token) {
            currentToken = token;
        }
    }
})
.factory('sessionInjector', ['sessionData', function (sessionData) {
    var sessionInjector = {
        request: function (config) {
            console.log("sending with token: " + sessionData.getToken());
            config.headers['x-header-sessionID'] = sessionData.getToken();
        }
    };
    return sessionInjector;
}])

.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push('sessionInjector');
}])

.run(['$http', 'configs', 'sessionData', function ($http, configs, sessionData) {
    $http.get(configs.authApiUrl + 'login').then(function (ret) {
        sessionData.setAuthData(ret);
        console.log("successfully authenticated with token " + sessionData.getToken());
    });
}])

.controller('TestCtrl', function($http){
    $scope.p1 = 'Uninitialized';

    $http.get('http://localhost/api/getData').then(function(ret){
        $scope.p1 = ret;
    });
});

问题在于TestCtrlrun 方法完成获取令牌之前发出http 调用(导致标头值包含[uninitialized-token])。

如何让控制器等待“运行”异步方法完成?

【问题讨论】:

  • 比如你可以把所有的http请求移到sessionData中,并提供一些接口来使用它
  • 如果您使用的是 ui-router,最好在解析主父状态时完成

标签: javascript angularjs angular-http-interceptors


【解决方案1】:

$http 拦截器可用于在其回调中返回 Promise。您可以使用它来拦截每个调用并将其延迟到 promise 被解决。

您应该了解 Promise 是如何工作的。

例子:

myModule.factory('tokenPromise', function($http) {
    return $http.get({url: 'myurl/token', bypassToken: true}).then(function(data) {
         // This is when your token webservice return, deal with the response here
         return data.token;
    });
});

myModule.factory('myHttpInterceptor', function($q, tokenPromise) {
  return {
    'request': function(config) {
      if (config.bypassToken) return config;
         // This ensures the token promise is resolved before proceeding with the request.
      return tokenPromise.then(function(token) {
         config.headers['x-header-sessionID'] = token;
         return config;
      });
    },
  };
});


myModule.config(function($httpProvider) {
     //wire the interceptor here
     $httpProvider.interceptors.push('myHttpInterceptor');
})

参考:http service on angular official docs

【讨论】:

  • 是的,我已经走上了这条路,但是 Angular 抱怨循环引用(http
  • 哦,我不介意这种情况。你是否尝试在配置中添加一个标志来强制不延迟这个特定的调用?我会更新我的答案。
  • 我已将此标记为答案,因为它确实解决了我遇到的特定问题,即使它并没有像发布问题的方式那样解决它......这是一个很好的答案。 ..thx
猜你喜欢
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 2014-09-16
  • 2014-08-03
相关资源
最近更新 更多