如何在 app.run 中使用异步代码
How use async code inside app.run?
我有一个运行块正在查询我的服务器以检查用户是否经过身份验证。
.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');
}
});
})
谢谢
你可以在 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');
}
});
}
或者一个更流行的替代方案(防止不断链接回调,使代码不可读 - 又名末日金字塔),是使用 Promises。
承诺采用异步函数并返回一个承诺,您可以使用该承诺来链接请求(例如,$http 方法返回您正在使用的名为 success
的承诺)。它在 ECMAScript 5 中不可用,但在 6 中可用。人们已经做了一堆Promises的实现,比如Kris Kowal的Q
,而Angular有一个名为$q
的这个库的精简版本。
因为这是异步调用,所以从技术上讲,第一个块已经完成,但它里面的调用没有完成。我唯一想到的是将承诺添加到用户服务中并通过它进行通信:
.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),它将再次需要相同的结构,这并不好,因此您需要更改逻辑。
相关文章:
- 如何从一系列级联异步代码中返回值
- 要按顺序执行的异步代码
- 谷歌分析-升级到异步代码
- 如何在node.js和MongoDb中混合javascript中的同步和异步代码
- 使用异步代码引发/捕获错误的替代方法
- 使我的异步代码与setTimeout同步.我需要承诺吗
- Node.js:异步代码 + js 闭包的问题
- 用外行的术语理解异步代码
- 以编程方式将同步代码转换为异步代码
- 在javascript中使用原型设计是否会对ajax调用和异步代码产生负面影响
- 如何在 app.run 中使用异步代码
- 执行异步代码时;退出“;事件
- 使用mocha为异步代码构建测试(请求)
- 这是在node.js中编写异步代码的正确方法吗
- durandal激活函数异步代码
- 链接多个.然后,一些没有异步代码的函数.最佳实践
- 自定义ESLint规则中的异步代码
- 节点js中可读的异步代码流
- 如何使用生成器在内部循环带有try-catch块的异步代码
- 在异步代码块中处理的多个ajax延迟调用的数组,后面是同步的最终代码块