仅当不共享订阅时,AsyncPipe初始值才为null [英] AsyncPipe initial value null only if subscription is not shared
问题描述
给出一个看起来像这样的模板
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.
有人可以指出我在这里缺少什么,为什么AsyncPipe
在apiRequest()
发出值之前不再返回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!
推荐答案
第一种情况:
- 计算ngIf表达式.它订阅了可观察对象,并且评估为null.因此,由于ngIf表达式是虚假的,因此不对[result]表达式进行求值.
- 可观察对象发出,并且ngIf表达式变为真.因此,对[结果]表达式进行了评估.它自己的异步管道订阅了Cold Observable,后者发送了另一个请求,并求值为null,因此将其作为输入传递给组件.
第二种情况:
- 计算ngIf表达式.它订阅了可观察对象,并且评估为null.因此,由于ngIf表达式是虚假的,因此不对[result]表达式进行求值.
- 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屋!