加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angular – 为什么组合的observable在使用Subject时不更新模板,

发布时间:2020-12-17 17:30:25 所属栏目:安全 来源:网络整理
导读:我在组件中定义了一个observable(result $),并通过异步管道在其模板上显示它.可观察量是通过combineLatest的其他2个可观察量(第一个$,第二个$)的组合. 如果其中一个observable或两者都过早发出(在我发现ngAfterContentInit之前),则生成的observable将不会发
我在组件中定义了一个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个观察者是主体,所以我的假设是主体是冷可观察者.它是否正确?

如果我延迟第一个$和第二个$的排放,一切正常:
组件:第一个$和第二个$稍后发出
????@零件({
??????选择器:’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$,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.如果我在订阅时没有价值,那么主题是可以的.除了这种差异,它们都会在订阅后收到发射值. —取决于你的用例.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读