【发布时间】:2021-05-19 23:08:05
【问题描述】:
问题
我有以下运算符:
const prepare = (value$: Observable<string>) =>
value$.pipe(
tap((x) => console.log("prepare: ", x)),
share()
);
const performTaskA = (removed$: Observable<string>) =>
removed$.pipe(tap((x) => console.log("taskA: ", x)));
const performTaskB = (removed$: Observable<string>) =>
removed$.pipe(
tap((x) => console.log("taskB 1: ", x)),
withLatestFrom(otherValue$),
tap((x) => console.log("taskB 2: ", x))
);
我这样称呼他们:
const prepared$ = value$.pipe(prepare);
const taskADone$ = prepared$.pipe(performTaskA);
const taskBDone$ = prepared$.pipe(performTaskB);
merge(taskADone$, taskBDone$).subscribe();
产生以下输出:
prepare: TEST
taskA: TEST
taskB 1: TEST
请注意,taskB 2 尚未被记录 - 似乎 taskBDone 可观察对象已停止在 performTaskB 中的 withLatestFrom(otherValue$)。
如果prepare 中的share 被删除,observable 不会停止,但它(不出所料)会导致prepare 执行两次,这是我不希望的。
问题
- 我怎样才能同时执行
performTaskA和performTaskB但prepare只执行一次? - 鉴于下面的调试说明,为什么
share会导致发射序列发生变化?
演示
分享(如上):https://codesandbox.io/s/so-share-with-latest-from-with-share-rtyex?file=/src/index.ts:663-853
无分享:https://codesandbox.io/s/so-share-with-latest-from-no-share-p702e
转到右侧的“测试”选项卡,确保控制台可见,然后单击“播放”按钮。
部分解释
调试withLatestFrom 很明显,当源(removed$) 发射时,ready 是false here,这会阻止发射。
这是因为当 share 存在时,输入 (otherValue$) 订阅在源之后发出,因此尚未设置 ready。 (或者是share导致源提前发射?)
但是当share 被删除时,输入订阅发出在源之前发出,这意味着ready 通过here 和here 设置为真,因此withLatestFrom 发出为预计。
【问题讨论】:
-
在
performTaskB中,您直接在withLatestFrom中使用value$- 而不是prepare返回的共享版本。但是removed$参数实际上是共享的value$,所以我们在这个函数中使用了两个不同版本的value$。这是故意的吗? -
这是故意的,因为它显示了我遇到的问题。但是我已经编辑了问题,现在
withLatestFrom引用了一个单独的变量,该变量更接近我的真实示例并且仍然显示问题。 -
谢谢-我认为解释可能与您今天的其他问题相似但不相同。在这种情况下,您传递的“TEST”可观察对象(以及
otherValue$)是什么? -
我通过
TestScheduler/marbles 将它们作为冷观测值传递 - 请参阅codesandbox.io/s/… - 这在某种程度上模仿了我的真实世界应用程序,其中value$是Subject和$otherValue已连接到 ngrx 选择器。无论哪种方式,我在这里和我的应用程序中都有同样的问题。谢谢。 -
@backtick 我已经深入研究了这个问题并相应地更新了问题。
标签: rxjs