Angular: 每次需要更新的时候我应该订阅()到http.get()吗?

Angular: Should I subscribe() to http.get() each time I need to update?

我想知道我是否使用了 Observable.subscribe() 太多次。

在我的组件 class 中,我有一个函数 loadData()。 它调用另一个函数 this.service.getData(),该函数使用 HttpClient.get() 向服务器执行 HTTP 请求。

目前在我的函数 loadData() 中,我订阅了 this.service.getData() 的结果。

每次用户点击 "Update" 按钮时,我想调用我的函数 loadData()。

问题

答案

代码示例

private loadData() {
    this.loading = true;
     const subscription = this.service.getData()
      .pipe(
  // console.log() with a delay added for test - START
  map(val => {
    window.setTimeout(() => {
      // This will print true.
      console.log('After delay: Is Subscriber closed?', subscription.closed);
    }, 10);
    return val;
  }),
    // console.log() with a delay added for test - END
    takeUntil(this.ngUnsubscribe))
      .subscribe(data => {
        this.data = data;
        // This will print false.
        console.log('Is Subscriber closed?', subscription.closed);
      },
      error => {
        console.error(error);
        throw error;
      },
      () => {
        this.loading = false;
      });
}
getData(): Observable<DataObject> {
    const uri = encodeURI(this.configService.getUri());
    const headers = new HttpHeaders();
    if (this.pipelineEtag) {
      headers.set('If-None-Match', this.pipelineEtag);
    }
    return this.http.get(uri, {
      headers: headers,
      observe: 'response'
    }).pipe(
      map(resp => this.processResponse(resp)),
      catchError(error => this.handleError(error, this.envProduction))
    );
}

这是正确的用法,创建多个订阅者没有风险。

来自文档:

The AsyncPipe subscribes (and unsubscribes) for you automatically.

Source


技术细节是,一旦 Http 请求完成,就会调用可观察对象的 .complete 方法,这会杀死所有当前订阅者。这意味着您的订阅者已创建、使用并立即被丢弃。

每次 HTTP 调用 returns 一个值时,Observable 就会完成。所以在服务中做这样的事情是安全的

loadData() { 

    return this.http.get<Data>(dataUrl).pipe(
      //  tap(data => console.log(data)), // eyeball results in the console
      catchError(err => this.handleError(err))
    );

}

然后调用

this.service.loadData().subscribe((data:Data) => do somthing)

您甚至可以调用 exhaustMap 或 switchMap 来控制 Observable 流程,以免 "hint" 服务器占用太多时间

所以最后

  • 我找到另一个 post :
  • 说明Angular代码实际上是在HTTP请求后调用observable.complete(),有延迟
  • 所以我修改了下面的代码以检查该事实和测试 证实是真的