【问题标题】:Waiting for data in an Angular Interceptor using an RxJs BehaviorSubject使用 RxJs BehaviorSubject 在 Angular 拦截器中等待数据
【发布时间】:2019-06-26 21:51:49
【问题描述】:

我是 rxjs 的新手 - 我了解大多数运算符,但我不了解 BehaviorSubjectfiltertake 的特定用法。

我想在 Angular 拦截器中更新 oauth 访问和刷新令牌对。我在这里和博客中看到的所有代码都是相同的——似乎有一种标准的方法来做到这一点。但是有一点我不明白。

作为an example,这部分将请求排队,直到有新的访问和刷新令牌可用。

private refreshSubject = new BehaviorSubject<any>(null);

// ...etc.

if (!this.refreshInProgress) {
  // request new access and refresh tokens from server
  // populate refreshSubject once tokens received
}
else {
  return this.refreshSubject.pipe(
    filter(result => result !== null),                      // <---- ???
    take(1),                                                // <---- ???
    switchMap(() => next.handle(this.addToken(request)))
  );
}

所有此类示例都说明请求会排队,直到refreshSubject 被新令牌填充,而魔法发生在filter

这是我不明白的。 rxjs docs 不是说 filter 导致等待 - 等待和排队在哪里/如何发生?

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    嗯,BehaviorSubject 的初始值为“NULL”(在进行获取新令牌的请求或套接字连接之前),您需要选择不同于 NULL 的值,为此我们使用“filter”运算符

    filter(result => result !== null), 
    

    这将仅将不同于 NULL 的值发送到 BehaviorSubject 的下一个管道步骤。

    现在我们只需要“获取”一个从 BehaviorSubject 发出的值(由于获取新令牌的方式,您必须这样做),为了做到这一点,我们使用“take”运算符。

    take(1),
    

    这只会发出 ONE 值,即使有 10 个发出的值,也只有第一个会被传送到下一个管道步骤。

    毕竟,您使用“switchMap”处理值,但请记住,每次获得新订阅时,BehaviorSubject 都会发出当前值(最后发出的值)。

    【讨论】:

    • 谢谢!然而,我明白这一切。问题是在令牌可用之前,请求如何排队。我以为take 终止了流,那么排队是怎么发生的呢?
    • 在您分享的示例中,没有排队,只有始终发出服务器发送的最后一个令牌的 BehaviorSubject,也了解实际的“排队”,我需要查看更多代码以及您如何使用 BehaviorSubject 将令牌请求“排队”。
    • 好吧,我就是这么想的,不用排队。代码来自我链接到的示例。每个这样的例子都说有排队,但我不相信。感谢您为我确认!
    • 我在这方面花了很多时间,我想我现在看到了我的困惑——你说得对,没有“排队”,但有“等待”。所有需要新的刷新令牌的失败请求都订阅了拦截器的 observable,因此它们实际上处于“等待”状态。一旦新令牌可用,该流就完成了,并且可以使用新令牌重试所有这些请求。所以实际上他们一直在“等待”,但不是因为使用了队列,而只是因为他们在等待可观察/订阅完成。这有意义吗?
    • 哈哈,这是一次学习体验——真正的问题是take:"An Observable that emits only the first count values emitted by the source Observable, or all of the values from the source if the source emits fewer than count values." 的文档。所以我想如果有零值,那么take(1) 会立即完成 - 但那不是真的!实际发生的是它会 WAIT 直到至少有一个值,然后完成! :-) 非常感谢您的帮助!
    猜你喜欢
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多