首页 > 解决方案 > 是否可以在 rxjs6 和 Angular 中共享订阅事件?

问题描述

我有简单地调用 api 的服务类。此服务类正在组件中使用。有没有办法让消费组件知道服务 api 的订阅何时完成?

现在我正在从消费组件向服务发送回调函数。回调函数是订阅函数的参数之一,这是我的理解。

class MyService {
constructor(httpClient: HTTPClient){}
fetchDetails (id, callback) {
 this.http.get('my/api/endpoint/url').subscribe(
  response => {
    // do something with response
  }
  error => { //do some processing for error}
  () => callback() // called when subscribe is done
 )
}
}
class MyList {
 constructor(myservice: MyService){}

 getDetails (id) {
  this.myservice.fetchDetails(id, this.detailsFetched);
 }
 detailsFetched () {
  // subscribe complete
  // do some processing like route to a state
 }
}

这目前对我有用,但不知何故,我觉得必须有更好的方法来做我想做的事。由于我是 rxjs 的新手,我无法理解如何实现它。

标签: typescriptangular6rxjs6

解决方案


您的解决方案是正确的,作为替代方案,我可以建议使用更具声明性的 RxJS 方式来编写类似的内容。

import { HttpClient } from '@angular/common/http';
import { shareReplay, finalize } from 'rxjs/operators';
import { Observable } from 'rxjs';

class MyService {
  constructor(private http: HttpClient) {}

  fetchDetails(id): Observable<any> {
    const stream$ = this.http
      .get(`my/api/endpoint/url/${id}`)
      .pipe(shareReplay());

    stream$.subscribe(
      (response) => {
        console.log(response);
      },
      (error) => {
        console.log(error);
      },
      () => {
        console.log('completed');
      },
    );

    return stream$;
  }
}

class MyList {
  constructor(private myservice: MyService) {}

  private getDetails(id) {
    this.myservice
      .fetchDetails(id)
      .pipe(finalize(() => this.detailsFetched()))
      .subscribe();
  }

  private detailsFetched() {
    // subscribe complete
    // do some processing like route to a state
  }
}

总而言之,您可以看到我是从 中返回ObservablefetchDetails(),它是用 创建的shareReplay()。它的作用是shareReplay()它只会创建 1 个网络调用并将其共享给订阅源 observable 的任何人,然后如果有人在 observable 完成后订阅,它将重播,以便以后的订阅者收到相同的事件。

还要看看我在getDetails哪里使用finalize()运算符来做你想做的事。当源 Observable 完成时,将调用传递给 finalize 运算符的回调。


推荐阅读