订阅被调用两次

问题描述 投票:0回答:5

我正在尝试创建一个表单来提交详细信息,但是当我订阅该服务时,订阅会完成两次。第一个是空数据,第二个是实际数据。

组件.ts

addBook() {
    this.errorMessage = null;
    this.fireService.getBook(this.bookDetails.isbn).subscribe(data => {
      console.log('subscribe called');
      if (null != data) {
        this.dbox.open(DialogBoxComponent, {
          data: { title: 'Error', content: 'Book is already present in Library. Select Edit book to modify the details', button: false }
        });
        this.errorMessage = 'Book is already present in Library. Select Edit book to modify the details';
      } else {
        this.fireService.addBook(this.bookDetails);
        this.dbox.open(DialogBoxComponent, {
          data: { title: 'Success', content: 'Book has been Added to Database', button: false }
        });
        this.router.navigateByUrl('/add-book');
      }
    });
  }

服务.ts

getBook(id) {
  console.log('called firebase get book');
  return this.db.doc(`/books/${id}`).valueChanges();
}

下图是chrome控制台的图片。这表明订阅被调用了两次,但 Firebase 服务没有被调用。

Chrome console logs: Image please click to view

chrome 控制台日志

called firebase get book
subscribe called
subscribe called

请帮忙

javascript angular typescript firebase angular5
5个回答
10
投票

这是因为当 Books 集合发生变化时, getBooks 返回的 observable 会发出一个新值。第一次没有具有相同 isbn 的书,因此数据为空。然后你添加一本书,所以 same observable 再次触发,这次是你刚刚添加的书

如果您只想获取一次数据, 您可以使用 take 只订阅一次。

this.fireService.getBook(this.bookDetails.isbn).take(1).subscribe(data => {
  console.log('subscribe called');

4
投票

就像 Chau Tran 所说,您可以过滤以获得有效的响应。如果您还没有,我会添加一种取消订阅的方式。在下面的代码中,

this.alive
是一个 true 字段,在 OnDestory 生命挂钩中变为 false。

this.fireService.getBook(this.bookDetails.isbn)
.takeWhile(() => this.alive)
.filter(data => !!data)
.subscribe(...)

1
投票

使用管道(take(1))

this.fireService.getBook(this.bookDetails.isbn).pipe(take(1)).
subscribe(data => {     console.log('subscribe called');

0
投票

在函数

addBook
中,您正在调用订阅。每次调用函数
addBook
时,您都在进行订阅调用,请避免在此类函数中使用订阅。确保仅在
onInit()
中订阅,以便每当您进行更改时它都会检查。


0
投票

我遇到了类似的问题,问题是订阅设置了两次,订阅观察者的函数在 ngOnChanges 中被调用,并且 ngOnChanges 被意外调用了两次。修复 ngOnChanges 调用两次也解决了这个问题

© www.soinside.com 2019 - 2024. All rights reserved.