AngularJS路由resolve中API请求需等待授权验证完成后执行
解决方案
这其实是AngularJS路由resolve机制的典型用法——通过依赖关系控制解析顺序。要实现仅在授权验证通过后才加载其他数据,你只需要让initData、dashboardData这些项依赖authorize即可,AngularJS会自动等待被依赖的resolve项完成后再执行后续逻辑。
步骤1:确保authorize返回Promise
首先要保证你的authSvc.checkAuthorization()方法返回一个Promise,验证通过时resolve,验证失败时reject(同时可以跳转登录页阻止路由加载):
$routeProvider.when('/dashboard', { templateUrl: 'template/dashboard.html', controller: 'dashCtrl', resolve: { // 先执行授权验证,返回Promise authorize: function(authSvc, $location, $q) { return authSvc.checkAuthorization() .then(function(isAuthorized) { if (!isAuthorized) { // 验证不通过,跳转登录页并reject阻止路由 $location.path('/login'); return $q.reject('用户未授权'); } // 验证通过,resolve(返回的值可以在后续依赖项中使用,也可以忽略) return isAuthorized; }); },
步骤2:让其他数据项依赖authorize
在initData、dashboardData的函数参数中注入authorize,AngularJS会自动等待authorize的Promise完成后,再执行这些数据加载逻辑:
// 依赖authorize,等待授权完成后再初始化数据 initData: function(authorize, dataSvc) { // 这里的authorize是前面resolve返回的结果,即使不用它,注入就会触发等待 return dataSvc.initData(); }, // 同理,dashboardData也依赖authorize dashboardData: function(authorize, dataSvc) { return dataSvc.getDashboardData(); } } });
为什么这能生效?
AngularJS的路由resolve机制会按依赖关系排序执行所有项:
- 如果一个
resolve项依赖另一个项(比如initData依赖authorize),Angular会先等待被依赖项的Promise完成(不管是resolve还是reject)。 - 只有当所有
resolve项都成功resolve后,才会加载对应的控制器和模板;如果有任何一项reject,路由会终止加载,你可以在catch里处理跳转或提示。
额外提示
- 如果你的
authSvc.checkAuthorization()本身已经返回Promise,那authorize函数直接返回它就行,不用额外包装(上面的示例是加了验证结果判断的场景)。 - 后续的
initData等函数里如果需要用到授权相关的信息(比如用户ID),可以直接使用authorize参数的值(也就是authSvc.checkAuthorization()resolve的结果)。
内容的提问来源于stack exchange,提问作者Abeez
相关产品推荐
相关产品推荐

