当前位置: 首页 > 知识库问答 >
问题:

一个可观察的多用户Rxjs/Angular共享不起作用

邴景山
2023-03-14

我在我的一个项目中使用angular 4,我正在进行一个http调用来获取数据。当数据从后端返回时,我会缓存数据,这样对于后续的请求,我就不必一次又一次地进行其余的调用。

getApplication(): Observable<Array<Application>> {
        return new Observable<Array<Application>>((observer) => {
            if (this.app&& this.app.length > 0) {
                observer.next(this.app)
            } else {
                this._http
                    .get<Application[]>(this.url)
                    .map((app) => this.mapToApp(app))
                    .subscribe((result: Array<Application>) => {
                        observer.next(result);
                    }, () => {
                        observer.next([]);
                    })
            }
        })
    }

这工作得很好。但是如果两个调用同时进行,我会看到网络选项卡中有两个请求而不是一个。所以我尝试共享()来满足“一个可观察的,多个订阅者”。

getApplication(): Observable<Array<Application>> {
            return new Observable<Array<Application>>((observer) => {
                if (this.app&& this.app.length > 0) {
                    observer.next(this.app)
                } else {
                    this._http
                        .get<Application[]>(this.url)
                        .map((app) => this.mapToApp(app))
                        .subscribe((result: Array<Application>) => {
                            observer.next(result);
                        }, () => {
                            observer.next([]);
                        })
                }
            }).share()
        }

但同样,我看到网络选项卡中有多个请求,而不是一个。要只打一个电话并与所有用户分享结果,必须做些什么?请帮帮忙。

共有2个答案

胡弘毅
2023-03-14

是否调用getApplication()方法两次?如果是,则创建两个不同的可观察值。

也许你应该遵循出版商/订户模式,使用主题来代替?

岳茂
2023-03-14

我的第一个建议是考虑按照这些思路在代码中进行一些简化

getApplication(): Observable<Array<Application>> {
      if (this.app && this.app.length > 0) {
         return Observable.of(this.app);
      }
      return this._http
                    .get<Application[]>(this.url)
                    .map((app) => this.mapToApp(app))
                    .do((result: Array<Application>) => {
                        this.app = result;
                    }
}

有了这个逻辑,您可以使用任何想要的逻辑进行缓存。您已经决定检查< code>this.app是否不为空,以及它是否包含一些元素。但是您可以使用任何其他逻辑,可能取决于输入参数。

一个不同的故事是同时发出两个呼叫的问题。在这种情况下,您可能希望<code>共享</code>Observable以便只共享一个订阅,<code>重播</code>最后记录的结果以便返回缓存值。

这样做的一种方法可以是

private cache$: Observable<Array<Application>>;

requestApplication(): Observable<Array<Application>> {
          return this._http
                        .get<Application[]>(this.url)
                        .map((app) => this.mapToApp(app))
                        .do((result: Array<Application>) => {
                            this.app = result;
                        }
}

getApplication() {
    if(!cache$) {
       cache$ = this.requestApplication().shareReplay(1);
    }
    return cache$;
}

这里的技巧是由共享重播运算符执行的。它的共享部分确保订阅被共享。缓冲区大小为1的重播部分确保始终返回存储的最后一个结果。

然后,您可能会面临偶尔清除缓存的问题。但这里的故事变得更加复杂,我建议你看这篇非常好的文章https://blog.thoughtram.io/angular/2018/03/05/advanced-caching-with-rxjs.html

 类似资料:
  • 在一个服务中,我有两个API调用,每个调用都返回一个可观察的,在我的组件中,我有一些条件,如果为true,我必须调用这两个函数,但我需要等待get()调用,这样我就可以使用get调用返回的参数执行post函数。如果为false,我只想用已经定义的参数调用post函数。 服务: 组成部分: 我不想重复帖子调用的代码,或者如果不可能的话,只是不要在另一个订阅()中使用订阅()。我怎么能这么做?没有异步

  • 我正在努力理解rxJs观察者/可观察的。 我有一个Angular应用程序,其中一个服务创建一个可观察的: 闲聊服务ts: 当聊天室中收到消息时。服务ts,消息(假定)是多播的: 两个组件以这种方式订阅可观察对象: 问题:只有一个(最后一个订阅的)收到消息。 问:我如何配置可观察到多播到所有订阅者?

  • 我在实现一个我已经实现的函数的可观察点击事件时遇到了麻烦。到目前为止,我看到的示例是使用或实现的,就像这样; 他们的html 现在考虑下面的实现。 组件技术 index.html 服务台 我的问题是如何使用我当前的,并且在使用我找到的方法时仍然能够订阅我的方法。(即本文中的示例代码)我理解(我认为)流,以及可观测的概念,但这是我最不理解的。 提前感谢您的帮助。

  • 我对Observables和RxJs是新手,我想对回报进行调整。如果第一个选择器返回某个值,我希望第二个选择器可以观察到。但是如果第一个选择器没有返回那个特定的值,我想返回false,而不是(false)。我已经走了这么远,但这返回了一个可观察的结果

  • 我试图将一个角度函数转换为可观察模式,因为它的当前实现与它有一些异步性。为了讨论这个问题,我们举一个简单的例子。 可以通过以下方式将其转换为使用可观察对象: 我所面临的问题(据我所知)是针对无法访问内部选择语句的情况。 如果使用常规主题,订阅函数肯定不会得到任何值,因为事件的顺序是: 函数被调用 主题已创建 值已设置 调用函数订阅,因此仅在此事件发生后获取值 如果使用了BehaviorSubjec

  • 我已经实现了一个angular应用程序,它请求一个项目列表来填充一个表格。在我的服务中,我有以下函数,它从服务器请求项目列表: 编辑:表获取数据的方式: 在HTML中,我将数据源绑定到mat表