是否可以在 rxjs 6 和 angular 中共享订阅事件?

Is it possible to share subscribe event in rxjs6 and angular?

我有服务 class,它只是调用 api。此服务 class 正在组件中使用。有没有办法让消费组件知道服务 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 的新手,所以我无法理解如何实现它。

您可以在管道中使用 rxjs 运算符 take。这样你就只订阅从你的可观察对象发出的第一个事件。

fetchDetails (id, callback) {
 this.http.get('my/api/endpoint/url').pipe(take(1)).subscribe(
  response => {
    // do something with response
  }
  error => { //do some processing for error}
  () => callback() // called when subscribe is done
 )
}

您的解决方案是正确的,作为替代方案,我可以建议使用更具声明性的 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
  }
}

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

另请查看 getDetails,我在其中使用 finalize() 运算符来执行您想要的操作。 传递给 finalize 运算符的回调将在源 Observable 完成时被调用。