RxJS - .subscribe() 与 .publish().connect() [英] RxJS - .subscribe() vs .publish().connect()

查看:24
本文介绍了RxJS - .subscribe() 与 .publish().connect()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这主要是 RxJs 最佳实践/方法问题,因为我的 POC 代码有效,但我是 RxJs 的新手.

This is mainly an RxJs best practice/approach question, since my POC code works but I'm brand new to RxJs.

问题归结为 .subscribe().publish().connect(),因为它们似乎都在做同样的事情.

The question boils down to .subscribe() vs .publish().connect(), since they both appear to do the same thing.

在我的 angular2 应用程序中,我有一个按钮调用一个函数来注销用户,它调用我的服务中的一个函数来执行一些服务器端操作并返回一个 URL 以将用户重定向到.为了发起请求,我调用 .subscribe() 来使 observable 开始产生值.我正在阅读一篇关于Cold vs Hot Observables"的文章,另一种方法是调用 .publish().connect() 而不是 .subscribe().这两种方法有什么好处.

In my angular2 app, I have a button that calls a function to log the user out, which calls a function in my service that performs some server side actions and returns me a URL to redirect the user to. In order to initiate the request I call .subscribe() to cause the observable to start producing values. I was reading an article on "Cold vs Hot Observables" and it another approach would be to call .publish().connect() instead of .subscribe(). Is there any benefit to either approach.

<a (click)="logout()">Logout</a>

注销功能如下所示:

logout.component.ts

logout() { this.authService.logout(); }

服务(实际注销)如下所示:

And the service (actual logout) looks like this:

auth.service.ts

logout() : Observable<boolean>  {
        this.http.get(this.location.prepareExternalUrl('api/v1/authentication/logout'))
            .map(this.extractData)
            .catch(this.handleError)
            .do((x: string) => { window.location.href = x; })
            .subscribe();    // Option A - 

        return Observable.of(true);

    }

auth.service.alternative.ts

logout() : Observable<boolean>  {
        this.http.get(this.location.prepareExternalUrl('api/v1/authentication/logout'))
            .map(this.extractData)
            .catch(this.handleError)
            .do((x: string) => { window.location.href = x; })
            .publish()  // Option B - Make connectable observable
            .connect(); // Option B - Cause the connectable observable to subscribe and produce my value       

        return Observable.of(true);
    }

推荐答案

subscribe().publish().connect() 的区别在于订阅它的源 Observable.考虑以下 Observable:

The difference between subscribe() and .publish().connect() is in when they subscribe to its source Observable. Consider the following Observable:

let source = Observable.from([1, 2, 3])

这个 Observable 在订阅时将所有值发送给 Observer.因此,如果我有两个观察者,那么它们会按顺序接收所有值:

This Observable emits all values to an Observer right when it subscribes. So if I have two Observers then they receive all values in order:

source.subscribe(val => console.log('obs1', val));
source.subscribe(val => console.log('obs2', val));

这将打印到控制台:

obs1 1
obs1 2
obs1 3
obs2 1
obs2 2
obs2 3

另一方面,调用 .publish() 返回一个 ConnectableObservable.这个 Observable 在它的构造函数中没有订阅它的源代码(在我们的例子中是 source ),并且只保留它的引用.然后你可以订阅多个观察者,没有任何反应.最后,您调用 connect() 并且 ConnectableObservable 订阅开始发出值的 source.这次已经有两个观察者订阅了,所以它一个一个地向他们发送值:

On the other hand calling .publish() returns a ConnectableObservable. This Observable doesn't subscribe to it's source (source in our example) in its constructor and only keeps its reference. Then you can subscribe multiple Observers to it and nothing happens. Finally, you call connect() and the ConnectableObservable subscribes to the source which starts emitting values. This time there're already two Observers subscribes so it emits values to both of them one by one:

let connectable = source.publish();
connectable.subscribe(val => console.log('obs1', val));
connectable.subscribe(val => console.log('obs2', val));
connectable.connect();

打印到控制台:

obs1 1
obs2 1
obs1 2
obs2 2
obs1 3
obs2 3

观看现场演示:http://plnkr.co/edit/ySWocRr99m1WXwsOGfjS?p=preview

这篇关于RxJS - .subscribe() 与 .publish().connect()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆