Angular 2+等待方法/可观察完成

Posted

技术标签:

【中文标题】Angular 2+等待方法/可观察完成【英文标题】:Angular 2+ wait for method / observable to complete 【发布时间】:2017-10-12 16:12:24 【问题描述】:

我需要检查后端的身份验证状态,但是代码在可观察返回完成之前完成。这将导致一个未定义的。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
    this.isAuthenticated();        
    return this.authenticated; 


isAuthenticated()
    this.loginService.isAuthenticated()
        .subscribe(status => this.authenticated = status)
 

我将如何更改此代码,以便在代码返回之前等待 observable 完成以获取经过身份验证的状态。

注意:Angular 的 canActivate 方法不允许我编写如下所示的代码:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
    this.loginService.isAuthenticated()
        .subscribe(status => 
            this.authenticated = status;
            return this.authenticated;
        );

这会导致以下错误:

“AuthGuard”类错误地实现了“CanActivate”接口。 属性“canActivate”的类型不兼容。 类型 '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => void' 不可分配给类型 '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => boolean |可观察 |公...'。 类型 'void' 不能分配给类型 'boolean |可观察 |承诺”。

对此错误的解决方案的建议也会有所帮助。

【问题讨论】:

我在尝试实现自定义身份验证保护时遇到了完全相同的问题,该保护授权/未登录用户,具有不同的角色。你拯救了我的一天。 【参考方案1】:

用 async / await 和 promise 解决了问题

LoginService 首先导入 toPromise:

import 'rxjs/add/operator/toPromise';

然后在 LoginService 中创建了一个异步方法

  async isAuthenticated()
     const response = await this.http.get('/login/authenticated').toPromise();
     return response.json();
  

然后在组件中:

async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
    this.loginStatus = await this.loginService.isAuthenticated();

    console.log("LOGGED IN STATUS: " + this.loginStatus);

    if (this.loginStatus == true)
        return true;
    

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/layout/login'],  queryParams:  returnUrl: state.url  );    

【讨论】:

【参考方案2】:

您可以将 observable 返回为 Observable<boolean>

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
    return this.loginService.isAuthenticated()
        .map(status => 
            console.log(status);
            this.authenticated = status;
            return true;
        ).catch((err) => 
            console.log(err);
            return Observable.of(false);
        );

【讨论】:

canActivate 应该返回 true 或 false,而不是 Observable,这可能吗? 另外,如果订阅,后端总是返回;对或错。我不应该添加 Subscribe() 方法吗? @phicon 这正是您的错误消息所说的,boolean | Observable | Promise。它应该返回一个布尔值、一个布尔值的可观察对象或一个布尔值的承诺。 this.authenticated 在您的原始代码中未定义。

以上是关于Angular 2+等待方法/可观察完成的主要内容,如果未能解决你的问题,请参考以下文章

等待多个可观察请求完成使用 RXSwift

在 foreach 中等待几个可观察的 rxjs 直到完成执行另一个

Java 等待线程完成

在 Angular 中组合可观察数据的正确方法是啥?

如何在茉莉花中为可观察的 finally 块编写单元测试 - Angular 2

Rxjs 可观察等待,直到满足某些条件