我应该取消订阅每个 ajax 调用吗?根据 RxJS 契约(Contract),我应该。因为 AJAX 调用不是流或事件,所以一旦完成它们就完成了。在这种特殊情况下使用 RxJS 的原因是什么?加类会变得一团糟(我知道 takeUntil,这不是这里的重点)。

public remove(data: IData): void {
  // unsubscribe from the previous possible call
  if (this.dataSubscription &&
      this.dataSubscription.unsubscribe) {
    this.dataSubscription.unsubscribe();
  }
  this.dataSubscription = this.dataService
    .delete(data.id)
    .subscribe(() => {
      this.refresh();
    });
}

public ngOnDestroy(): void {
  // unsubscribe on deletion
  if (this.dataSubscription &&
      this.dataSubscription.unsubscribe) {
    this.dataSubscription.unsubscribe();
  }
}

与简单的 promise 相比有什么优势,在执行后看起来更干净并被销毁?
public remove(data: IData): void {
  this.dataService
    .delete(data.id)
    .then(() => {
      this.refresh();
    });
}

这是数据服务代码
@Injectable()
export class DataService {
  constructor(private _httpClient: HttpClient) { }

  public delete(id: number): Observable<IModel> {
    return this._httpClient.delete<IModel>(`${this._entityApiUrl}/${id}`);
  }
}

最佳答案

有限的、冷的 Observables 通常不需要取消订阅。在这方面,它们就像 Promises 一样工作。假设您在您的服务中使用 Angular 的 HttpClient,则不需要取消订阅——它很像那种情况下的 Promise。

首先,要澄清一些事情——在您的 Promise 示例中,您通过将 Promise 分配给 this.dataSubscription 来强制管理 Promise。在进行该调用后,任何在 HTTP 调用后任意时间调用 this.dataSubscription.then() 的内容都将收到 Promise.resolve() 并调用该 .then() 函数。 Promise.resolve() 返回的新 Promise 会在执行后被清理,但只有当你的类被销毁时,你的 this.dataSubscription Promise 才会被清理。

但是,不将该 Promise 分配为属性甚至更清晰:

public remove(data: IData): void {
  this.dataService
    .delete(data.id)
    .then(() => {
      this.refresh();
    });
}

另外,Promise 将在其作用域结束时被清理,而不是在类的销毁时。

Observables,至少是像这样的有限“类 Promise”,以大致相同的方式工作。您不需要管理返回的 Subscription 购买 .subscribe() 方法,因为它会执行然后被清理,因为它没有被分配为属性:
public remove(data: IData): void {
  this.dataService
    .delete(data.id)
    .subscribe(() => {
      this.refresh();
    });
}

它是一个有限的 Observable 并在订阅后完成,因此再次调用 subscribe 将返回一个新的 Subscription 并重新调用 Observable 的函数。

强制管理这些订阅确实很麻烦,通常表明事情可以做得更好。

与 RXJS 订阅管理的不同之处在于,RXJS 可以成为一种非常强大的工具,它的用途不仅仅是管理异步 AJAX 调用。您可以拥有向数百个订阅者发布数据的热门 Observable,向许多订阅者管理自己的流的主题,永不停止发射的无限 Observable,管理状态并返回其他 Observable 的高阶 Observable,等等。在这种情况下,最好取消订阅实践,但老实说不会导致极端情况之外的性能问题。

一个很好的比较是 Observable.fromEvent() 属性。就像在 removeEventListener 之后正确使用 addEventListener 是最佳实践一样,您应该正确取消订阅此 Observable。然而,就像 removeEventListener 一样,......它并不是一直都在完成,通常不会导致当今平台的问题。

此外,引用声明的“RxJS 契约(Contract)”:这是同一文档的摘录:
When an Observable issues an OnError or OnComplete notification to its observers, this ends the subscription. Observers do not need to issue an Unsubscribe notification to end subscriptions that are ended by the Observable in this way.
有限的 Observables 会在它们发出后完成自己,不需要取消订阅。

关于ajax - Angular/RxJS 我应该取消订阅每个 ajax 调用吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48430082/

10-16 21:19