在javascript

时间:2017-07-24 02:42:10

标签: javascript angular rxjs

这个问题在某种程度上与这些问题有关12,但它们没有以可以帮助我的方式解决javascript中的同步可观察对象问题。

我目前处于角度4或角度,我有一条受保护的路线等待两名警卫解决。其中两个按预期返回true,但第二个需要太长时间才能在canActivate方法完成后得到答案。示例代码如下。我该怎么做才能让我的第二个后卫同步解决?

我是新手这个javascript和observables异步的做事方式!对不起,如果这个问题很愚蠢。

  1. 首先是authGuard:

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
    boolean {
         if(this.cookieService.check('token'))return true;
         console.log(true); //For demostration purpose
    }
    
  2. 第二个authGuard:

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
    boolean {
         this.roleService.checkRole('admin') // this service take some time
         .subscribe(
             response=>{
                 //Simple logic checking the response.
                 console.log(true); 
                 return true;
             },
             error=>{
                 //some logic with the error
                 console.log(false);
                 return false;
             }
    
         )
    console.log('End of authguard method');
    }
    
  3. roleService:

    checkRole(role:string): 
    boolean {
           return  this.http.post(Url, body,requestOptions)
                            .map(this.processData)
                            .catch(this.handleError);
    }
    
  4. 4.Console显示:

        true                        // from authGuard 1
        "End of authguard method"   // from authGuard 2
        true                        // from authGuard 2
    

    路由器无法导航到所需的路由,因为第二个真的来得太晚了。我也在订阅之前尝试了first()运算符,并且第一个运算符不等待role.Service中的observable来解析。

1 个答案:

答案 0 :(得分:1)

CanActivate的界面是

interface CanActivate { 
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean
}

这意味着除了原始布尔值之外,它还将接受PromiseObservable的返回类型。您面临的问题是您正在尝试将Observable视为布尔值,而不是它。你应该重构你的第二个authGuard:

canActivate(
  route: ActivatedRouteSnapshot, 
  state: RouterStateSnapshot
): Observable<boolean> {
  return this.roleService
     .checkRole('admin') // this service take some time
     // Any success value is mapped to true
     .mapTo(true)
     // Any error will log and return false
     .catch(e => {
       console.log('Encountered an error checking role', e);
       return Observable.of(false);
     })
     // This logs when this *actually* completes
     .finally(() => console.log('End of authguard method'));
}

我们之所以需要这样做是因为作为一般模式,我们不知道Observable何时会发出,我们只知道我们想要做什么。我们实际上正在返回一个将完成最终的工作流程,而不是尝试分配单个值。