【问题标题】:Multiple Guards calling async function多个Guards调用异步函数
【发布时间】:2017-11-06 13:45:08
【问题描述】:

我有两个 Guard,Guard1 和 Guard2。 Guard1 返回一个 Observable,Guard2 返回布尔值。

canActivate: [Guard1, Guard2]

假设Guard2会返回false,Guard1的请求会自动取消吗?还是无论如何都会执行调用?

【问题讨论】:

  • 这取决于调用的顺序
  • 我认为 Guard1 是先执行的,但它是异步的。然后Guard2是假的。我可以在开发者工具中看到 xhr 请求被取消,但我不知道为什么。
  • 你是在告诉守卫异步调用被取消了?
  • 是的,通话被取消
  • 那么我猜看守二,即布尔值首先被执行,然后该调用被取消,因为守卫二未被调用,不确定需要检查

标签: angular angular2-observables angular2-guards canactivate


【解决方案1】:

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

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

我创建了一个简单的 HTTP 缓存来保持较低的请求数量。我只在一个 Guard 中触发了一个请求,但该请求从未完成,因为其他 Guard 更早返回 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();

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

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

【讨论】:

    猜你喜欢
    • 2021-11-26
    • 1970-01-01
    • 2023-02-10
    • 2018-11-17
    • 2021-06-27
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多