AngularJS:如何留在 'run' 方法中直到完成
AngularJS: how to stay in 'run' method until it finishes
我有一个简单的场景 - 我希望使用拦截器初始化我的 http 调用,拦截器将在 headers(某种令牌)中添加一个值。
问题是令牌也是通过 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;
});
});
问题是 TestCtrl
在 run
方法完成获取令牌之前发出了一个 http 调用(导致 header 值具有 [uninitialized-token] 在它的值中)。
如何让控制器等待 'run' 异步方法完成?
$http 拦截器可用于 return 回调中的承诺。您可以使用它来拦截每个调用并将其延迟,直到承诺得到解决。
你应该明白 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 调用,拦截器将在 headers(某种令牌)中添加一个值。
问题是令牌也是通过 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;
});
});
问题是 TestCtrl
在 run
方法完成获取令牌之前发出了一个 http 调用(导致 header 值具有 [uninitialized-token] 在它的值中)。
如何让控制器等待 'run' 异步方法完成?
$http 拦截器可用于 return 回调中的承诺。您可以使用它来拦截每个调用并将其延迟,直到承诺得到解决。
你应该明白 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');
})