多个警卫调用异步功能

时间:2017-06-05 17:51:45

标签: angular angular2-observables angular2-guards canactivate

我有两名后卫,Guard1和Guard2。 Guard1返回一个Observable,Guard2返回Boolean。

canActivate:[Guard1,Guard2]

假设Guard2将返回false,Guard1的请求是否会自动取消?或者电话会被执行吗?

1 个答案:

答案 0 :(得分:2)

Guard1的请求将被取消,Guard2对此负责。我将它与if语句进行比较,其中将条件与&&组合在一起,除了没有定义Guards的执行/结果的顺序(由于某些Guards可能是异步的而且有些不 - 而且你希望它们在大多数情况下并行运行。如果任何condition / Guard返回false,则总结果为false,如果其中一个已经返回false,则无需评估/等待任何其他条件/ Guard,因此运行请求将被取消。

如果你依赖所有后卫(从后卫发出的请求)执行直到他们全部完成,有很多方法可以实际控制这个 - 但是他们做的不仅仅是保护路线,请记住这一点。当我遇到这种情况时,我将使用我的情况更详细地解释这一点:

我创建了一个简单的HTTP缓存来保持较低的请求数。我有一个请求仅在一个Guard内被解雇,但该请求从未完成,因为其他Guards之前返回false并且请求被取消。这个请求永远不会被缓存,因为我没有得到任何结果,因为请求总是被取消(简化版听起来没用,但它演示了我想说的内容)。然后我这样做了:

  • 我创建了一个“包装器”Observable,Guard将其作为结果返回
  • 这个“包装器”Observable只传递请求的结果(第二个Observable),作为Guard的结果
  • Angular只会“取消”返回的“包装器”Observable,因此即使“包装器”Observable将被取消,请求也会完成
像这样:

const wrapperSubject = new Subject<boolean>();
this.http.get(apiUrl, this.reqOptions)
  .map(res => {
     // extract data from result ...
     // add to cache ...
     return booleanGuardResult;
   })
  .takeUntil(wrapperSubject)
  .subscribe(booleanGuardResult=> {
    wrapperSubject.next(booleanGuardResult);
    wrapperSubject.complete();
   });
return = wrapperSubject.asObservable();

这适用于我的情况,请求已缓存。

如果你依赖于async Guard执行的顺序,我可以想象创建一个简单的Guard来处理它,组合多个其他Guards以定义的顺序执行(使用RxJS combineLatest和/或类似的运营商。有很多,取决于你想要实现的目标......)。如果所有Guards都返回boolean而不是Observable或Promise,则Guard执行的顺序是在路由中定义的顺序 - 我无法想象Angular会改变执行顺序。