【问题标题】:Refresh/reload a Hot Observable sequence with RxJS使用 RxJS 刷新/重新加载 Hot Observable 序列
【发布时间】:2017-05-24 15:38:18
【问题描述】:

我正在使用 Angular 2 开发门户。登录时,我向服务器发出请求以获取已登录的用户配置文件。获取用户配置文件的方法返回一个 observable,当应用程序加载时,它在 6 个不同的地方订阅。

如果我使用冷的 observable,这将导致对服务器进行 6 次 API 调用。所以我通过添加 .publishLast().refCount() 切换到一个 hot observable。

这导致单个请求共享数据,因为用户配置文件不会在后续请求中更新。

问题从这里开始:

现在我有一个编辑配置文件功能,它通过 HTTP PUT 更新用户配置文件,因此,我想使之前订阅的 Observables 过期并以某种方式再次触发序列,以便再次执行 API 并接收订阅更新数据。

有什么方法可以重新启动/重新触发已经订阅的可观察序列?

这是获取用户可观察的代码

fetch(){
    this.userObservable = Observable.fromPromise(this.getToken())
      .switchMap(token => {
        let headers = new Headers();
        headers.append('Authorization', `Bearer ${token}`);
        return this.http.get('/api/v1/admin/users/me?includes=role', {headers: headers})
      })
      .map((res: Response) => {
        let retVal: any = {
          data: new Deserializer({
            keyForAttribute: 'camelCase'
          }).deserialize(res.json())
        };
        this.user = retVal.data as MpUser;
        this.user.role = MpRoles[retVal.data.role[0].name];
        return this.user;
      })
      .publishLast()
      .refCount();
  }

【问题讨论】:

    标签: angular rxjs rxjs5


    【解决方案1】:

    你可以尝试引入subject来触发fetch:

    private fetchTrigger = new BehaviorSubject(null);
    
    triggerFetch() {
      this.fetchTrigger.next();
    }
    
    fetch() {
      this.userObservable = Observable
        .combineLatest(
          Observable.fromPromise(this.getToken()),
          this.fetchTrigger
        )
        .switchMap(([token]) => {
          ...
        })
        ...
        .publishLast()
        .refCount();
    }
    

    请注意,在此示例中,token 仅检索一次。如果您需要在每次刷新时获取新令牌:

    private fetchTrigger = new BehaviorSubject(null);
    
    triggerFetch() {
      this.fetchTrigger.next();
    }
    
    fetch() {
      this.userObservable = this.fetchTrigger
        .switchMap(() => Observable.fromPromise(this.getToken()))
        .switchMap(token => {
          ...
        })
        ...
        .publishLast()
        .refCount();
    }
    

    【讨论】:

    • 恐怕这行不通,因为令牌会在超时后刷新。我们正在使用 Keycloak SSO 进行身份验证。
    • @Mohammad Umair Khan,检查答案
    • BehaviorSubject 将在第一次订阅时返回初始化值,而不是等待 API 调用完成。这打破了流程,我正在尝试主题,但还没有运气。
    • @MohammadUmairKhan,你的意思是http.get没有被执行?
    • http.get 将被执行,但在它完成之前,BehaviorSubject 将返回它初始化的空值。
    猜你喜欢
    • 2018-12-27
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 2015-02-11
    • 2010-12-03
    • 1970-01-01
    相关资源
    最近更新 更多