angular – 为什么组合的observable在使用Subject时不更新模板,
我在组件中定义了一个observable(result $),并通过异步管道在其模板上显示它.可观察量是通过combineLatest的其他2个可观察量(第一个$,第二个$)的组合.
如果其中一个observable或两者都过早发出(在我发现ngAfterContentInit之前),则生成的observable将不会发出值. 组件:不起作用 @Component({ selector: 'my-app',templateUrl: './app.component.html',styleUrls: [ './app.component.css' ] }) export class AppComponent { result$: Observable<number>; first$= new Subject<number>(); second$= new Subject<number>(); constructor() {} ngOnInit(){ this.result$= combineLatest( this.first$,this.second$ ).pipe( map(([first,second]) => { // This is not printed to the console console.log('combined obs emitted value'); return first + second; }) ); console.log('first and second emit value'); this.first$.next(2); this.second$.next(4); } ngAfterContentInit() { console.log('ngAfterContentInit'); } } 执行顺序是: 1.第一和第二发出价值 2.ngAfterContentInit 我的假设是在ngAfterViewInit中已经渲染了模板并且已经进行了订阅.由于observable在此之前发出值,因此不会通知组件.这只能意味着生成的observable很冷(因此,您需要在它发出值之前进行订阅). 2个观察者是主体,所以我的假设是主体是冷可观察者.它是否正确? 如果我延迟第一个$和第二个$的排放,一切正常: result$: Observable<number>; first$= new Subject<number>(); second$= new Subject<number>(); constructor() {} ngOnInit(){ this.result$= combineLatest( this.first$,second]) => { console.log('combined obs emitted value'); return first + second; }) ); // Solution 1: add timeout setTimeout(() => { console.log('first and second emit value'); this.first$.next(2); this.second$.next(4); }) } ngAfterContentInit() { console.log('ngAfterContentInit'); } } 订单现在是: > ngAfterContentInit 所以,这是因为订阅是在observable发出值之前进行的吗? 如果我将observable更改为BehaviorSubject,即使在订阅发生之前发出值,一切也都有效.这是否意味着BehaviourSubjects是热门观察者? @Component({ selector: 'my-app',styleUrls: [ './app.component.css' ] }) export class AppComponent { result$: Observable<number>; first$= new BehaviorSubject<number>(0); second$= new BehaviorSubject<number>(0); constructor() { } ngOnInit(){ this.result$= combineLatest( this.first$,second]) => { // This is not printed to the console console.log('combined obs emitted value'); return first + second; }) ); console.log('first and second emit value'); this.first$.next(2); this.second$.next(4); } ngAfterContentInit() { console.log('ngAfterContentInit'); } } Stackblitz 解决方法
Q1:2个可观察者是主体,所以我的假设是主体是冷可观察者.它是否正确?
A1:answer from this question说主题本身很热.这个article描述了热,冷和主题. Q2:再次,这是因为订阅是在观察者发出价值之前做出的吗? A2:是的.订阅后,订阅将在您订阅后收到值.你引入的延迟()应该给它时间. 为什么?这是因为BehaviorSubject总是保存一个值并在订阅时发出它,而Subject没有保存值,它只是从生产者发送到当前订阅者的值. Details. 问题3:这是否意味着BehaviourSubjects是热门观察者? 答:见A1. 如果这不能直接回答您的问题,请道歉.我只是想说…在处理Subject和BehaviorSubject时,我并不关心它们是热还是冷. 相反,我问:“当我订阅时,我是否希望observable始终保持一个值?”.如果是,我使用BehaviorSubject.如果我在订阅时没有价值,那么主题是可以的.除了这种差异,它们都会在订阅后收到发射值. —取决于你的用例. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |