Angular 9 return Observable 来自 Observable
Angular 9 return Observable from an Observable
我正在寻找一种方法 return 从另一个 Observable 到一个 Observable。我发现您可以使用 pipe 和 map 运算符来做到这一点,但它似乎对我不起作用。我做错了什么?
我正在使用 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:请注意,您也必须在需要时退订。如果您不熟悉这些概念,我建议您阅读 that 文章。
就像函数只有 运行 当你调用它们时里面的代码一样,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();
}
}
有两种类型的可观察量:热和冷。我不会进入热门可观察对象,因为它与问题没有任何关系。您可以找到更多信息 here
冷可观察对象——顾名思义——在订阅之前不会开始处理它的内部语句。因此,在这种情况下,当您订阅组件时,它会触发所有可观察到的最内层 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))
);
}
}
还有一点要注意,您在组件中使用了 map
运算符,但没有 return 语句。在那种情况下,它将 return 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();
}
}
有更优雅的方法可以关闭打开的订阅。看这里:
我正在寻找一种方法 return 从另一个 Observable 到一个 Observable。我发现您可以使用 pipe 和 map 运算符来做到这一点,但它似乎对我不起作用。我做错了什么?
我正在使用 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:请注意,您也必须在需要时退订。如果您不熟悉这些概念,我建议您阅读 that 文章。
就像函数只有 运行 当你调用它们时里面的代码一样,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();
}
}
有两种类型的可观察量:热和冷。我不会进入热门可观察对象,因为它与问题没有任何关系。您可以找到更多信息 here
冷可观察对象——顾名思义——在订阅之前不会开始处理它的内部语句。因此,在这种情况下,当您订阅组件时,它会触发所有可观察到的最内层 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))
);
}
}
还有一点要注意,您在组件中使用了 map
运算符,但没有 return 语句。在那种情况下,它将 return 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();
}
}
有更优雅的方法可以关闭打开的订阅。看这里: