簡體   English   中英

Angular 9 從 Observable 返回 Observable

[英]Angular 9 return Observable from an Observable

我正在尋找一種從另一個 Observable 返回一個 Observable 的方法。 我發現您可以使用管道映射運算符來做到這一點,但它似乎對我不起作用。 我究竟做錯了什么 ?

我正在使用Angular 9.1.12rxjs ~6.5.4

示例:服務 1

import { Observable, of } from 'rxjs';

export class Service1 {

  test(): Observable<string> {
      console.log(1);
      return of('hey');
  }
}

服務2

import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export class Service2 {

  constructor(private service1: Service1) {}

  test(): Observable<string> {
    return this.service1.test().pipe(
      map((value: string) => {
        console.log(2);
        return value;
      })
    );
  }
}

成分

import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export class Component implements OnInit {

  constructor(private service2: Service2) {}

  test(): Observable<void> {
    return this.service2.test().pipe(
      map((value: string) => {
        console.log(3);
      }));
    }
  }
}

控制台只會輸出1

這是合理的,因為您從不訂閱observables因此它們從未實際發出或運行。

您應該像這樣訂閱組件。

this.test().subscribe();

我創建了一個stackblitz來玩。

PS:請注意,您還必須在需要時取消訂閱。 如果你不熟悉這些概念,我建議你閱讀文章。

正如函數只在你調用它們時運行內部代碼一樣, Observables只在你訂閱它們時運行它們的代碼。

您會看到1輸出,因為您調用了this.service1.test()

您看不到23因為您從未訂閱那些Observables

export class Component implements OnInit {

  constructor(private service2: Service2) {}

  test(): void {
    this.service2.test().pipe(
      map(_ => console.log(3))
    ).subscribe();
  }
  
}

有兩種類型的 observables:熱的和冷的。 我不會進入熱門的觀察對象,因為它與這個問題沒有任何關系。 你可以在這里找到更多信息

Cold observables——顧名思義——在它被訂閱之前不會開始處理它的內部語句。 因此,在這種情況下,當您訂閱組件時,它會觸發所有 observables 直到最內部of('hey')

export class Component implements OnInit {
  constructor(private service2: Service2) {}

  ngOnInit() {
    this.test().subscribe();
  }

  test(): Observable<void> {
    return this.service2.test().pipe(
      tap((value: string) => console.log(value))
    );
  }
}

這里要注意的另一件事是,您在沒有 return 語句的組件中使用了map運算符。 在這種情況下,它將返回undefined map一般用於轉換傳入的語句。 tap運算符更適合這里。 它用於執行副作用。

退訂

此外,除非發出錯誤或明確完成,否則開放訂閱不會關閉。 因此,在使用后關閉打開的訂閱總是一個好主意。

例如。 在 Angular 中,通常的做法是在ngOnDestroy鈎子中關閉它,以便在組件關閉時關閉它。

export class Component implements OnInit, OnDestroy {
  sub: Subscription;

  constructor(private service2: Service2) {}

  ngOnInit() {
    this.sub = this.test().subscribe();
  }

  test(): Observable<void> {
    return this.service2.test().pipe(
      tap((value: string) => console.log(value))
    );
  }

  ngOnDestroy() {
    if (!!this.sub)
      this.sub.unsubscribe();
  }
}

有更優雅的方法來關閉打開的訂閱。 見這里: https : //stackoverflow.com/a/60223749/6513921

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM