【发布时间】:2019-12-20 11:00:37
【问题描述】:
从下面的 sn-p 可以看出,
如果一个承诺被忽略,withLatestFrom 永远不会完成。
const { combineLatest, range } = rxjs;
const { withLatestFrom } = rxjs.operators;
const a$ = range(1, 5);
const b$ = Promise.resolve('never');
a$.pipe(
withLatestFrom(b$),
).subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.2/rxjs.umd.js" integrity="sha256-mNXCdYv896VtdKYTBWgurbyH+p9uDUgWE4sYjRnB5dM=" crossorigin="anonymous"></script>
const b$ = of(1); 就可以了
文档并不清楚这种行为, 有什么提示吗?
【问题讨论】:
-
这是一个与事件循环有关的时间问题。
from(p())只是让你的s1.pipe(withLatestFrom(s2b))赶上它。如果你延迟s1的发射,即使是 0,const s1 = of(1).pipe(delay(0))它将被推到下一个循环,s2b发射它的值,你会得到你想要的输出[1, 'b']。 stackblitz.com/edit/rxjs-epnbko -
当你说它是一个“时间问题”时,你的意思是我的实现有问题(我假设是这个)还是 rxjs 的一个已知错误/怪癖?如果是前者,我不完全理解为什么这是一个问题。我认为
withLatestFrom会在 observable 完成时发出。并且由于它是一个可观察对象,因此 何时 可观察对象完成并不重要。 -
时间问题我的意思是它与浏览器排队和处理任务和微任务的方式有关。当然,这也与
withLatestFrom的工作方式有关。在你的最后一行s1被订阅并发出,但s2b还没有发出任何东西(承诺还没有解决)所以withLatestFrom(s2b)不会发出任何东西,因为s2b没有最新值.withLatestFrom不会等待其内部可观察的s2b发射。 -
很抱歉,我没有意识到您在谈论 JS 事件循环,我正在阅读您的评论,因为它与 rxjs 可观察对象的工作方式有关。现在知道
withLatestFrom不会等待来自可观察对象的发射清除了我错误地思考这个问题的地方。非常感谢。 -
不确定我添加到我的答案中的运算符是否是一个更好的解决方案,但它可以实现我不希望的承诺,并且如果使用
shareReplay(1)传入 long living observable 它将起作用因为那很好。这可以改进吗/这是一个糟糕的主意吗?
标签: javascript promise functional-programming rxjs reactive