简体   繁体   English

多次订阅可观察的 rxjs

[英]Subscribing multiple times to an observable rxjs

I'm trying to achieve the following:我正在努力实现以下目标:

I have an Observable that can be subscribed to multiple times, although I only want to do some processing once.我有一个可以订阅多次的 Observable,虽然我只想做一次处理。

export class DataLoader
{
    private loaded = false;
    private data: Data;
    private observable = null;

    load(): Observable<Data> {
        if(this.loaded) {
            console.log('Already loaded');
            return Observable.create((obs) => {
                obs.next(this.data);
                obs.complete();
            })
        }

        if(this.observable === null) {
            console.log('Creating observable');
            this.observable = Observable.create((obs) => {

                console.log('firing xhr');
                let xhr;

                xhr.onload = () => {
                    this.data = data;
                    this.loaded = true;
                    obs.next(data);
                    obs.complete();
                    this.observable = null;
                }

                xhr.onerror = () => {
                    obs.error(error);
                    this.observable = null;
                }
            });
        }

        return this.observable;
    }
}

Lets say I use this DataLoader in 2 different places, the 'xhr' will only be done once.假设我在 2 个不同的地方使用这个 DataLoader,'xhr' 只会执行一次。

...
Dataloader.load().subscribe();
...
#At another point in the code
Dataloader.load().subscribe();
...

Console:控制台:

Creating observable
firing xhr
Already Loaded

This works correctly as long as the requests aren't fired off too quickly after each other.只要请求不会在彼此之后太快地被触发,这就能正常工作。

To demonstrate, lets put this in a for loop:为了演示,让我们把它放在一个 for 循环中:

for(let i = 0; i<10; i++) {
    DataLoader.load().subscribe();
}

In this case the console looks like this:在这种情况下,控制台如下所示:

Creating observable
firing xhr
firing xhr
firing xhr
firing xhr
firing xhr
firing xhr
firing xhr
firing xhr
firing xhr
firing xhr

How could I manage to use this in a for loop ?我怎么能在 for 循环中使用它? I've been looking into a Subject / BehaviourSubject but I cannot seem to make it work.我一直在研究一个主题/行为主题,但我似乎无法让它发挥作用。

Cookies for thoughs饼干的想法

I Solved it using the following:我使用以下方法解决了它:

if(this.observable === null) {
    console.log('Creating observable');
    let source = Observable.create((obs) => {

        console.log('firing xhr');
        let xhr;

        xhr.onload = () => {
            this.data = data;
            this.loaded = true;
            obs.next(data);
            obs.complete();
            this.observable = null;
        }

        xhr.onerror = () => {
            obs.error(error);
            this.observable = null;
        }
    });

    let subject = new Subject();

    this.observable = source.multicast(subject);

    this.observable.connect();
}

http://reactivex.io/rxjs/manual/overview.html#multicasted-observables http://reactivex.io/rxjs/manual/overview.html#multicasted-observables

I opted for using simple promises since all I needed was a multicast event, but it seems rxjs deals with it already with "Subjects"我选择使用简单的承诺,因为我需要的只是一个多播事件,但似乎 rxjs 已经用“主题”处理了它

  return this.service.add(this.formModel.value, this.imageFile)
    .toPromise() // this.subscribe((x) => value = x, (err) => reject(err), () => resolve(value));
    .then(id => this.formVm.editMode(id));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM