[英]Angular 9 return Observable from an Observable
我正在尋找一種從另一個 Observable 返回一個 Observable 的方法。 我發現您可以使用管道和映射運算符來做到這一點,但它似乎對我不起作用。 我究竟做錯了什么 ?
我正在使用Angular 9.1.12和rxjs ~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()
。
您看不到2
或3
因為您從未訂閱那些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.