【问题标题】:Withlatestfrom not emitting data from async observableWithlatestfrom 不从异步 observable 发出数据
【发布时间】: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


【解决方案1】:

根据 fridoo,我对 withLatestFrom 的工作方式有错误的理解。 withLatestFrom 不会等待其源发出。延迟源 observable 或通过其他方式等待异步操作 (combineLatest) 会导致 observable 正确发射。

【讨论】:

  • 你为什么不用combineLatest(s1, s2b)?如果s2b 是一个Promise,它无论如何只会发出一次,所以combineLatests2b 发出时发出的事实应该不是问题。
  • 我想在我正在进行的项目中异步访问 API 的 Promise 和长期存在的 observable 上使用 withLatestFrom。为了简洁起见,我只在代码中包含了 Promise,因为我相信这两个用例的根本原因都可以通过带有 Promise 的示例来回答。不过你是对的,如果这只是我担心combineLatest 的一个承诺,它会工作得很好。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多