源发出时管道可观察对象不发出
Piped observable not emitting when source emits
public lotId$ = new Subject<number>();
@Input() public set lotId(value: number) {
this.lotId$.next(value);
};
public results$ = this.lotId$.asObservable().pipe(
skipWhile(lotId => !lotId),
switchMap(lotId => this.logicService.getMappedTakeOffTasksForLot(lotId)),
tap(console.log)
);
在上面的代码中,results$
不会在每次 lotId$
发出时发出。有人知道为什么吗?代码在创建组件时运行 results$
一次,然后再也不会运行。
编辑:源发出 58。
编辑:当我从 Subject
更改为 BehaviorSubject
时它起作用了。为什么?我希望我能早点尝试。
results$ does not emit every time lotId$ emits.
在 lotId$
发出之前发生的对 results$
的订阅将收到这些值。换句话说,迟到的订阅者不会收到先前的值(“迟到的订阅者”我的意思是在发生一些排放后订阅)。
假设您在模板中使用 async
管道,results$
的订阅在视图初始化之后才会发生,但在此之前会调用 @Input() setter发生了。
您会发现,如果您在构造函数中订阅(只是为了实验),派生的 results$
实际上会发出初始值。
所以,应该很清楚为什么改成 BehaviorSubject
有效;订阅后,它会向新订阅者发出最新的先前值。
但是,BehaviorSubject
需要默认值(当然会发送给新订阅者)。发出默认值可能并不总是合适的,因此您可以改用 ReplaySubject(1)
,它也会向新订阅者发出以前的值,但不需要默认值。
下图显示了模板根据使用的主题类型收到的输出 (Subject
/ ReplaySubject
/ BehaviorSubject
):
如果组件有可选的 @Input()
,我使用 BehaviorSubject
,因为需要默认值。如果需要输入,我使用 ReplaySubject(1)
,因此除非消费者提供输入,否则我的逻辑不会执行。
这里有一些 StackBlitz,您可以在其中查看 Angular 生命周期挂钩的顺序以及订阅发生的时间。
public lotId$ = new Subject<number>();
@Input() public set lotId(value: number) {
this.lotId$.next(value);
};
public results$ = this.lotId$.asObservable().pipe(
skipWhile(lotId => !lotId),
switchMap(lotId => this.logicService.getMappedTakeOffTasksForLot(lotId)),
tap(console.log)
);
在上面的代码中,results$
不会在每次 lotId$
发出时发出。有人知道为什么吗?代码在创建组件时运行 results$
一次,然后再也不会运行。
编辑:源发出 58。
编辑:当我从 Subject
更改为 BehaviorSubject
时它起作用了。为什么?我希望我能早点尝试。
results$ does not emit every time lotId$ emits.
在 lotId$
发出之前发生的对 results$
的订阅将收到这些值。换句话说,迟到的订阅者不会收到先前的值(“迟到的订阅者”我的意思是在发生一些排放后订阅)。
假设您在模板中使用 async
管道,results$
的订阅在视图初始化之后才会发生,但在此之前会调用 @Input() setter发生了。
您会发现,如果您在构造函数中订阅(只是为了实验),派生的 results$
实际上会发出初始值。
所以,应该很清楚为什么改成 BehaviorSubject
有效;订阅后,它会向新订阅者发出最新的先前值。
但是,BehaviorSubject
需要默认值(当然会发送给新订阅者)。发出默认值可能并不总是合适的,因此您可以改用 ReplaySubject(1)
,它也会向新订阅者发出以前的值,但不需要默认值。
下图显示了模板根据使用的主题类型收到的输出 (Subject
/ ReplaySubject
/ BehaviorSubject
):
如果组件有可选的 @Input()
,我使用 BehaviorSubject
,因为需要默认值。如果需要输入,我使用 ReplaySubject(1)
,因此除非消费者提供输入,否则我的逻辑不会执行。
这里有一些 StackBlitz,您可以在其中查看 Angular 生命周期挂钩的顺序以及订阅发生的时间。