angularjs 同步請求_AngularJS 应用请求设置同步问题~

你这个问题看似简单,但实际上有点模糊:“run 只运行一次”这个先觉条件到底有什么影响呢?

看了半天我才明白你真正的问题在于你要知道用户的登录状态是否还有效,因为 SPA 应用不需要刷新页面,所以你的 run 只有运行一次的机会,因而如果用户不刷新浏览器且使用了很长时间(可能超过了 session 的有效期)那么你无法判断用户的登录还是否有效了。我说的没错吧?

实际上你这个问题根源不在前端,而在后端的 API 那里。如果你是 session 验证且会过期失效,那么失效与否不应该是用一个固定的 API Endpoint(也就是你例子里的 app.URL.login)来检查,而是应该在每一次 API 请求里都检查,并且如果 session 失效就返回给客户端一个特定的信息。

接下来就像 @dolymood 说的那样,在客户端用拦截器预先做好对此特定信息的处理,一旦收到就清空本地缓存的登录和用户信息然后跳转至 login。这才是解决你的问题的根本之道,和用不用 $q 以及 run 能否运行多次没有任何关系。

另外如有可能,还可以把 session 验证机制换成 token 验证机制,它好处会更多一些,特别是可以避免 cookie 带来的一些烦恼。不过 token 验证判断是否失效的道理和过程也和上述类似,无论如何后端 API 总是要反馈给客户端必要的信息的,不是通过固定的接口去“拉”这个信息,而是访问任何接口的时候都把信息“推”给客户端。

如果你完全触碰不到后端,只有一个固定的 API 来帮你判断登录状态的话(好可怜),那么到还有一个方法可以让你摆脱 run 只运行一次的困扰。不过先把它的缺陷说在前头:这个机制是依赖客户端应用的状态变更的!如果你的应用里有无须状态变更就可以请求 API 的业务逻辑,那就会出现“漏网之鱼”。什么意思?比如说你的页面里有很多链接/按钮,点击它们不会改变应用的状态而是直接发起异步请求,那就没有检查登录失效的先决条件了。除非你干脆写个拦截器把所有的 HTTP 请求都加一层登录失效检查,但这样也太蠢了……

OK,说正事:

看你的代码,你应该是用了 ui-router 的,那么你是否知道 ui-router 有一个 abstract state 机制可以利用一下?细节不多说了,自己看 ui-router 的文档,反正如果你写了一个顶级的 abstract state 就意味着其他任何状态的变更都会“继承”这个顶级抽象状态的逻辑定义。这样的 state 有点类似于 run(但作用领域是不同的,我倾向于把和业务逻辑无关的但是需要在进入应用之前的动作写在 run 里,而把和业务逻辑相关的,会频繁“动作”的行为放入 abstract state),于是可以在这里做一层“登录验证保护伞”。

所以你要做两件事情:

写一个 service,内容和你放在 run 里面的代码差不多(回过头看一下你这个逻辑也还是太“蠢”了,不请求就不可能知道是否失效,不慢才怪……)

顶级抽象状态里写一个 resolve,内容就是使用这个 service

于是其他任何状态的变化都必须先 resolve 这个“保护逻辑”,这就可以做到不依赖只运行一次的 run 了。

@dolymood 你提到的第一种情况,如果是前后分离的架构,后端是没有条件往页面里写信息的;即使可以也还是无法判断登录状态是否有效,因为 SPA 不刷新的……

@M_J 理解“状态”这个概念对于写 SPA 是至关重要的,就拿本问题来说吧,你之所以卡在 “run 只能运行一次该怎么办” 这个坑里,就是因为你没有意识到 run 和应用状态变化是无关的,它只负责应用整体的初始化逻辑。而你要的有效性检查则伴随着应用状态的变化而进行,所以你和 run 较劲就是“问道于盲”了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值