rxjs如何获取两个诺言中并非无效的第一个值

发布于 2025-01-25 00:12:15 字数 2641 浏览 0 评论 0原文

我试图围绕RXJS CONCAT的工作原理,以及它如何与Promises合作。

我有两个可观察到:

Current -Confriencation $排放null

newconfircation $发出新的确认

可以解释为什么这是有效的:

const finalConfirmation$ = currentConfirmation$.pipe(
    switchMap((conf) => {
      if (!conf) {
        return newConfirmation$
      }

      return of(conf)
    })
  )

但是这不是

const finalConfirmation$ = concat(currentConfirmation$, newConfirmation$).pipe(find((conf) => !!conf))

不起作用,我的意思是我的意思是我的意思是,我的意思是与该测试有关。 switchmap版本和concat版本

test("updateConfirmation should create the confirmation if it doesn't exist", (done) => {
    updateConfirmation({ value: true, symbol: 'LTCUSD', name: 'LTC_TEST_CONFIRMATION_999' }).subscribe((conf) => {
      expect(conf.entityData).toEqual({ value: true, symbol: 'LTCUSD', name: 'LTC_TEST_CONFIRMATION_999' })
      done()
    })
  })

我也很想知道是否有更好的方法来完成上述方法。

编辑: 这是测试的所有相关代码:

export const confirmationRepository$ = client$.pipe(
  switchMap(async (client) => client.fetchRepository(schema)),
  delayWhen((cr) => from(cr.createIndex())),
  shareReplay(1)
)

export const updateConfirmation = (newData: Partial<Confirmation>) => {
  // TODO: Just don't process the search if we get empty strings
  const currentConfirmation$ = getConfirmation(newData.symbol || ' ', newData.name || ' ')
  const newConfirmation$ = createConfirmation(newData)

  // const finalConfirmation$ = concat(currentConfirmation$, newConfirmation$).pipe(find((conf) => !!conf))
  const finalConfirmation$ = currentConfirmation$.pipe(
    switchMap(async (conf) => {
      if (!conf) {
        return newConfirmation$
      }
      return of(conf)
    }),
    concatAll(),
    combineLatestWith(confirmationRepository$),
    concatMap(async ([conf, confRepo]) => {
      conf.value = !!newData.value
      await confRepo.save(conf)
      return conf
    })
  )

  return finalConfirmation$
}

export const getConfirmation = (symbol: string, name: string) => {
  return confirmationRepository$.pipe(
    switchMap((cr) => cr.search().where('symbol').equals(symbol).and('name').equals(name).first())
  )
}

export const getConfirmations = (symbol: string) => {
  return confirmationRepository$.pipe(switchMap((cr) => cr.search().where('symbol').equals(symbol).returnAll()))
}

I'm trying to wrap my head around how RxJS concat works, and how it works with Promises in general.

I have two observables:

currentConfirmation$ emits null

newConfirmation$ emits a new confirmation

Could someone explain why this works:

const finalConfirmation$ = currentConfirmation$.pipe(
    switchMap((conf) => {
      if (!conf) {
        return newConfirmation$
      }

      return of(conf)
    })
  )

But this does not

const finalConfirmation$ = concat(currentConfirmation$, newConfirmation$).pipe(find((conf) => !!conf))

By not works I mean this test passes with the switchMap version and times out with the concat version

test("updateConfirmation should create the confirmation if it doesn't exist", (done) => {
    updateConfirmation({ value: true, symbol: 'LTCUSD', name: 'LTC_TEST_CONFIRMATION_999' }).subscribe((conf) => {
      expect(conf.entityData).toEqual({ value: true, symbol: 'LTCUSD', name: 'LTC_TEST_CONFIRMATION_999' })
      done()
    })
  })

I would also love to know if there is a better approach to accomplishing the above than what I have come up with.

Edit:
Here is all the relevant code for the test:

export const confirmationRepository$ = client$.pipe(
  switchMap(async (client) => client.fetchRepository(schema)),
  delayWhen((cr) => from(cr.createIndex())),
  shareReplay(1)
)

export const updateConfirmation = (newData: Partial<Confirmation>) => {
  // TODO: Just don't process the search if we get empty strings
  const currentConfirmation$ = getConfirmation(newData.symbol || ' ', newData.name || ' ')
  const newConfirmation$ = createConfirmation(newData)

  // const finalConfirmation$ = concat(currentConfirmation$, newConfirmation$).pipe(find((conf) => !!conf))
  const finalConfirmation$ = currentConfirmation$.pipe(
    switchMap(async (conf) => {
      if (!conf) {
        return newConfirmation$
      }
      return of(conf)
    }),
    concatAll(),
    combineLatestWith(confirmationRepository$),
    concatMap(async ([conf, confRepo]) => {
      conf.value = !!newData.value
      await confRepo.save(conf)
      return conf
    })
  )

  return finalConfirmation$
}

export const getConfirmation = (symbol: string, name: string) => {
  return confirmationRepository$.pipe(
    switchMap((cr) => cr.search().where('symbol').equals(symbol).and('name').equals(name).first())
  )
}

export const getConfirmations = (symbol: string) => {
  return confirmationRepository$.pipe(switchMap((cr) => cr.search().where('symbol').equals(symbol).returnAll()))
}

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

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

发布评论

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

评论(1

瑾夏年华 2025-02-01 00:12:15

concat仅执行每个可观察到的可观察到的并顺序返回每个可观察到的,并且它不会在介于两者之间进行任何突变,也没有提供任何其他方法来添加条件检查。

我可以看到您的示例使用查找在满足给定条件时完成流的过程,但它可能不像switchmap 版本

concat only executes each observable passed in and returns each of them sequentially, and it does not mutate anything in between nor does it provide any other means to add conditional checks.

I can see your example using find that kinda hack the way through, as it completes the stream when the given condition is met, but it is probably not as semantic or natural as the switchMap version

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