最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Observable subscribe called multiple times? - Stack Overflow

programmeradmin0浏览0评论

I have the following Observable:

dataService.ts

findMessages(chatItem: any): Observable<any[]> {
    return Observable.create((observer) => {
        this.firebaseDataService.findMessages(chatItem).subscribe((firebaseItems: any[]) => {
              // do something
                observer.next(somedata);
        });
    });
}

which calls this function:

firebaseDataService.ts

findMessages(chatItem: any): Observable<any[]> { // populates the firelist
    return this.af.database.list('/message/', {
        query: {
            orderByChild: 'negativtimestamp'
        }
    }).map(items => {
        const filtered = items.filter(
            item => ((item.memberId1 === chatItem.memberId1 && item.memberId2 === chatItem.memberId2)
                || (item.memberId1 === chatItem.memberId2 && item.memberId2 === chatItem.memberId1))
        );
        return filtered;
    });
}

The dataService.findMessages(chatItem) function is only ever called once.

This observes the firebase list. So if any items on the list change, this Observable is fired.

Problem

If the function is accessed, or one item is added to the list, the Observer is fired as expected, but the // do something line is called multiple times. I would only expect it to be called once.

Question

  • Is there a way to enforce that it's only called once?
  • Or once it's called for the first time, to break out of the
    subscribe?
  • Or, is my code pletely wrong?

Any advise appreciated.

I have the following Observable:

dataService.ts

findMessages(chatItem: any): Observable<any[]> {
    return Observable.create((observer) => {
        this.firebaseDataService.findMessages(chatItem).subscribe((firebaseItems: any[]) => {
              // do something
                observer.next(somedata);
        });
    });
}

which calls this function:

firebaseDataService.ts

findMessages(chatItem: any): Observable<any[]> { // populates the firelist
    return this.af.database.list('/message/', {
        query: {
            orderByChild: 'negativtimestamp'
        }
    }).map(items => {
        const filtered = items.filter(
            item => ((item.memberId1 === chatItem.memberId1 && item.memberId2 === chatItem.memberId2)
                || (item.memberId1 === chatItem.memberId2 && item.memberId2 === chatItem.memberId1))
        );
        return filtered;
    });
}

The dataService.findMessages(chatItem) function is only ever called once.

This observes the firebase list. So if any items on the list change, this Observable is fired.

Problem

If the function is accessed, or one item is added to the list, the Observer is fired as expected, but the // do something line is called multiple times. I would only expect it to be called once.

Question

  • Is there a way to enforce that it's only called once?
  • Or once it's called for the first time, to break out of the
    subscribe?
  • Or, is my code pletely wrong?

Any advise appreciated.

Share Improve this question edited May 8, 2017 at 11:08 Richard asked May 8, 2017 at 9:55 RichardRichard 8,96534 gold badges123 silver badges255 bronze badges 6
  • stackoverflow./questions/43831736/… – martin Commented May 8, 2017 at 10:12
  • Hi Martin, thanks for the ment. I do however get, [ts] Property 'multicast' does not exist on type 'Observable<any[]>'.. I may need to investigate a little further. – Richard Commented May 8, 2017 at 10:49
  • 1 => resolved by: import 'rxjs/add/operator/multicast'; – Richard Commented May 8, 2017 at 10:55
  • I am not sure how to construct the parameters for multicast(parameters). It looks like I need a Rx.Subject, but what is this? How do i get this? – Richard Commented May 8, 2017 at 11:04
  • use take(1) if you need to have only one emition – Julia Passynkova Commented May 8, 2017 at 15:14
 |  Show 1 more ment

1 Answer 1

Reset to default 3

but the // do something line is called multiple times

It is called in the callback passed to this.firebaseDataService.findMessages(chatItem).subscribe. The subscribe function will fire whenever there is a new item. If you only want to take one item you can use the take operator

More

Docs on take : https://github./Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/take.md

发布评论

评论列表(0)

  1. 暂无评论