我有一个运行块,它正在查询我的服务器以检查用户是否已通过身份验证。
.run(function($http, userService){
var base_url = 'http://server.com:3000';
$http.get(base_url + '/users/isloggedin')
.success(function(data, status, headers, config){
userService.setUserData(data.userData);
userService.setIsUserLoggedIn(true);
});
})
稍后,我有另一个需要第一个运行块信息的运行。这个问题是我的运行代码有异步代码,我第一次没有得到userService.getIsUserLoggedIn()的真值。
如何判断angularjs仅在第一个运行块完成后执行第二个运行块?
第二个运行块:
.run(function($rootScope, $location, $state, userService){
//Run to handle authentication
var authOnly = ['/painel'];
var unAuthOnly = ['/home'];
var checkAuthRoute = function(url){
var exist = authOnly.indexOf(url);
return exist > -1;
};
var checkUnAuthRoute = function(url){
var exist = unAuthOnly.indexOf(url);
return exist > -1;
};
$rootScope.$on('$stateChangeStart', function(evt, toState, toParams, fromState, fromParams){
console.log(toState.url + ' ' + fromState.url + ' - ' + userService.getIsUserLoggedIn());
if(!userService.getIsUserLoggedIn() && checkAuthRoute(toState.url)){
console.log('Aqui..');
evt.preventDefault();
$state.go('login');
}
});
})
由于
答案 0 :(得分:1)
您可以使用回调在Javascript中创建链异步请求。这样的事情可能有用:
.run(function($http, $rootScope, $location, $state, userService){
var base_url = 'http://server.com:3000';
$http.get(base_url + '/users/isloggedin')
.success(function(data, status, headers, config){
userService.setUserData(data.userData);
userService.setIsUserLoggedIn(true);
handleAuth($rootScope, $location, $state, userService);
});
})
在上面的.run
代码之前定义此函数:
function handleAuth($rootScope, $location, $state, userService){
var authOnly = ['/painel'];
var unAuthOnly = ['/home'];
var checkAuthRoute = function(url){
var exist = authOnly.indexOf(url);
return exist > -1;
};
var checkUnAuthRoute = function(url){
var exist = unAuthOnly.indexOf(url);
return exist > -1;
};
$rootScope.$on('$stateChangeStart', function(evt, toState, toParams, fromState, fromParams){
console.log(toState.url + ' ' + fromState.url + ' - ' + userService.getIsUserLoggedIn());
if(!userService.getIsUserLoggedIn() && checkAuthRoute(toState.url)){
console.log('Aqui..');
evt.preventDefault();
$state.go('login');
}
});
}
或一个更受欢迎的替代方案(为了防止使代码不可读的回调的不断链接 - 也就是末日金字塔),是使用{{3} }。
promise使用异步函数,返回一个promise,您可以使用它来链接请求(例如,$ http方法返回您使用的名为success
的promise) 。它在ECMAScript 5中不可用,但将在6中。人们已经做了许多Promises的实现,比如Kris Kowal的Q
,而Angular有一个名为$q
的这个库的精简版本。
答案 1 :(得分:0)
因为这是异步调用,所以技术上第一个块已经完成,但是其中的调用不是。我想到的唯一一件事就是在userService中添加promise并通过它进行通信:
.run(function($http, $q, userService){
var base_url = 'http://server.com:3000';
var deferred = q.defer();
$http.get(base_url + '/users/isloggedin')
.success(function(data, status, headers, config){
userService.setUserData(data.userData);
userService.setIsUserLoggedIn(true);
deferred.resolve();
});
userService.setPromise(deferred.promise);
})
在第二轮中:
.run(function(userService){
userService.getPromise().then(function(){
//code that requires first run to finish
});
})
但是如果某个地方需要从第二次运行完成代码(我的意思是只在第二次运行后才进行smth),它将再次需要相同的结构,并且这不是很好,所以你需要改变逻辑。