订阅被调用两次

新手上路,请多包涵

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

组件.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控制台日志:图片请点击查看

铬控制台日志

called firebase get book
subscribe called
subscribe called

请帮忙

原文由 Abhijith 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 313
2 个回答

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

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

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

原文由 David 发布,翻译遵循 CC BY-SA 3.0 许可协议

正如 Chau Tran 所说,您可以过滤以获得有效响应。如果您还没有,我会添加一种取消订阅的方式。在下面的代码中 this.alive 是一个真实的字段,在 OnDestory 生命挂钩中变为假。

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

原文由 Kate S 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题