仅当不共享订阅时,AsyncPipe初始值才为null [英] AsyncPipe initial value null only if subscription is not shared

查看:151
本文介绍了仅当不共享订阅时,AsyncPipe初始值才为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个看起来像这样的模板

Given a template that looks like something like this

<some-component
  *ngIf="someColdObservable$ | async"
  [result]="someColdObservable$ | async"
></some-component>

和一个看起来像这样的可观察对象:

and an observable that looks like this:

someColdObservable$: this.store.pipe(
  select(isAllowedToDoThis),
  filter(Boolean),
  flatMap(() => apiRequest())
);

someColdObservable$被订阅了两次(如预期的那样),这反过来又发出了两个api调用(这显然是代码的味道,但是现在让我们忽略它).

The someColdObservable$ gets subscribed to twice (as expected), which in turn issues two api calls (this is obviously a code smell, but let's disregard that at the moment).

在这种情况下,some-component不包含任何null检查,并且如果apiRequest在模板中对AsyncPipe求值之前导致some-component抛出cannot access x of null(由于[result]此时仍为null)请参见AsyncPipe参考资料.

In this scenario some-component does not contain any null checks, and AsyncPipe will return null if apiRequest has not emitted a value before the AsyncPipe is evaluated in the template resulting in some-component throwing a cannot access x of null (as [result] is still null at this point) see AsyncPipe source for reference.

这是所有预期的行为(或者至少在阅读源代码之后),但是,当我尝试通过在someColdObservable$上添加shareReplay来发出两个请求来缓解该问题时,我也解决了[result]被在apiRequest()发出值之前为null.这对我来说毫无意义,因为我希望AsyncPipe仍返回null

This is all expected behaviour (or at least after reading the source) however, when I try to mitigate the issue with making two requests by adding the shareReplay to someColdObservable$ I also fix the issue of [result] being null before the apiRequest() emits a value. This makes little sense to me as I would expect AsyncPipe to still return a null _latestValue here, leaving the cannot access x of null error unfixed. But for some reason adding shareReplay fixes both of the aforementioned issues.

这类似于共享时的角度可观察到的行为很奇怪,但是仍然是为什么shareReplay解决该问题的悬而未决的问题.

This is similar to Angular observable behavior odd when shared however, there is still the unanswered question of why shareReplay fixes the issue.

有人可以指出我在这里缺少什么,为什么AsyncPipeapiRequest()发出值之前不再返回null吗?

Would someone be able to point out what I am missing here and why AsyncPipe no longer returns null before apiRequest() emits a value?

感谢任何指针和输入,谢谢!

Appreciate any pointers and input, thanks!

推荐答案

第一种情况:

  1. 计算ngIf表达式.它订阅了可观察对象,并且评估为null.因此,由于ngIf表达式是虚假的,因此不对[result]表达式进行求值.
  2. 可观察对象发出,并且ngIf表达式变为真.因此,对[结果]表达式进行了评估.它自己的异步管道订阅了Cold Observable,后者发送了另一个请求,并求值为null,因此将其作为输入传递给组件.

第二种情况:

  1. 计算ngIf表达式.它订阅了可观察对象,并且评估为null.因此,由于ngIf表达式是虚假的,因此不对[result]表达式进行求值.
  2. observable发出,并且ngIf表达式变为true.因此,对[结果]表达式进行了评估.它自己的异步管道订阅了hot observable,后者立即重播上一次发出的内容,并且不再发送请求.因此,将表达式的值计算为非null值,并将其作为输入传递给组件.

比使用shareReplay更好的解决方案是将异步管道的结果存储在变量中并使用它:

A better solution than using shareReplay would be to store the result of the async pipe in a variable and use it:

<some-component
  *ngIf="someColdObservable$ | async as result"
  [result]="result"
></some-component>

这篇关于仅当不共享订阅时,AsyncPipe初始值才为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆