多个订阅导致源流两次发射

发布于 2025-01-20 20:27:13 字数 1236 浏览 1 评论 0原文

我想使用rxjs收听点击,执行事务并跟踪事务状态:

function performTransaction() {
  const status = {
    '0': 'pending',
    '1': 'success'
  }
  return interval(1000).pipe(take(2), map((i) => status[`${i}`]))
}

const click$ = new Subject<void>()

const claimTxnState$ = click$.pipe(switchMap(() => {
  console.log('performing transaction') // -> runs once which is expected
  return performTransaction()
}))

claimTxnState$.subscribe((v) => {
  console.log('claimTxnState', v);
})

export default function App() {

  return (
    <div className="App">
      <button onClick={() => click$.next()}>click me</button>
    </div>
  );
}

这会导致执行事务要输出一次,这是预期的。

但是我想将sipertxnstate $传输到更多位置:

const claimIsPending$ = claimTxnState$.pipe(map((claim) => claim === 'pending'))

claimIsPending$.subscribe((v) => {
  console.log('claimIsPending', v);
})

现在导致执行事务要输出两次,我理解这是因为这些是在每种订阅上重新创建的冷可观察物。但是我不想要这个。我只希望我的perstransaction被调用一次。我该如何实现?

完整示例。

I want to use RxJS to listen to clicks, perform a transaction, and keep track of the transaction status:

function performTransaction() {
  const status = {
    '0': 'pending',
    '1': 'success'
  }
  return interval(1000).pipe(take(2), map((i) => status[`${i}`]))
}

const click$ = new Subject<void>()

const claimTxnState$ = click$.pipe(switchMap(() => {
  console.log('performing transaction') // -> runs once which is expected
  return performTransaction()
}))

claimTxnState$.subscribe((v) => {
  console.log('claimTxnState', v);
})

export default function App() {

  return (
    <div className="App">
      <button onClick={() => click$.next()}>click me</button>
    </div>
  );
}

This causes performing transaction to be output once, as is expected.

But I want to pipe claimTxnState$ to more places:

const claimIsPending$ = claimTxnState$.pipe(map((claim) => claim === 'pending'))

claimIsPending$.subscribe((v) => {
  console.log('claimIsPending', v);
})

This now causes performing transaction to be output twice, which I understand because these are cold observables that get recreated on each subscription. But I don't want this. I only want my performTransaction to get called once. How can I achieve this?

Complete example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱的十字路口 2025-01-27 20:27:13

当我输入问题时,我找到了答案。我需要使用共享操作员将可观察到的可观察到的可观察到cold转换为热>热。这具有共享sipertxnstate $之间的效果(即.pipes(...)):

const claimTxnState$ = click$.pipe(
  switchMap(() => {
    console.log('performing transaction')
    return performTransaction()
  }),
  share() // <- this is the interesting line
)

sandbox。

/Autumn-framework-piyymy?file=/src/app.tsx“ rel = ” “ nofollow noreferrer”>更多细节。

I found the answer as I was typing the question. I need to use the share operator to convert the observable from cold to hot. This has the effect of sharing claimTxnState$ between all subscribers (i.e. .pipes(...)):

const claimTxnState$ = click$.pipe(
  switchMap(() => {
    console.log('performing transaction')
    return performTransaction()
  }),
  share() // <- this is the interesting line
)

Sandbox.

More detail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文