RxJS 中以前的订阅会发生什么?

What happens to previous Subscriptions in RxJS?

虽然我已经很习惯使用 RxJS 和反应式编程,但有一件事一直困扰着我,我无法理解。

假设我们有一个简单的函数,每次有人点击按钮 SCAN

时都会 运行
function scan() {
   this.startScaning(10).subscribe(scannedItem => console.log(scannedItem))
}

在我们的扫描函数中,我们使用 startScanning 方法开始扫描(即对于蓝牙设备)10 秒,它 returns 我们订阅的一个可观察对象,我们记录所有发现的 devices/items.

好的,到目前为止一切顺利,但令我困扰的是如果用户连续点击按钮 10 次会发生什么。以前的订阅会怎样?我该如何处理呢?我是否需要每次都退订,是否需要完全退订?

一个很好的解释将不胜感激,可能进一步readings/examples,谢谢

您可以在单击时将函数提交更改为另一个什么都不做的 class,当订阅 return 结果调用 class 再次将按钮更改为调用这个函数

它并没有解决 RxJS 问题只是你的问题,只是让按钮在等待结果时无用

我想你也可以使用 observables 将每个调用映射到一个变量,但在你的情况下,在循环 运行

时阻止函数调用似乎更好

我处理这个问题的方法是在进程为 运行 时翻转一个布尔值并将按钮的 [disabled] 属性 绑定到该值,例如

isScanning: boolean
function scan() {
    this.isScanning = true
    this.startScaning(10).subscribe({
        next: scannedItem => console.log(scannedItem),
        complete: () => this.isScanning = false
    })
}

<button (click)="scan()" [disabled]="isScanning">Click me!</button>

(您可能还想添加某种指示器,指示它在禁用按钮时正在处理 - 我喜欢使用 Font Awesome 的 spinner icons*ngIf="isScanning"

至于其他的,就看startScaning这个方法具体实现的怎么样了。很可能你有十个独立的可观察对象,每个对象会在各自点击后十秒自动完成,所以不需要担心手动取消订阅或任何事情,除非它是一个非常繁重的过程(但 IMO 你仍然应该出于用户体验原因,无论如何禁用该按钮)。

再次查看您的问题,我假设您使用的是 Angular,但您实际上并没有这么说。如果你不是,一般原则是一样的,唯一的区别是你需要使用不同的方式来设置按钮的 disabled 状态。