javascript - RxJS 如何从两个 promise 中获取第一个不为空的值

标签 javascript rxjs rxjs-observables

我正在努力思考 RxJS concat 的工作原理,以及它通常如何与 Promises 一起工作。

我有两个可观察对象:

currentConfirmation$ 发出 null

newConfirmation$ 发出一个新的确认

谁能解释一下为什么会这样:

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()))
}

最佳答案

concat 只执行传入的每个 observable 并按顺序返回它们中的每一个,它不会改变两者之间的任何内容,也不会提供任何其他方法来添加条件检查。

我可以看到您的示例使用 find 有点破解方法,因为它会在满足给定条件时完成流,但它可能不像 那样语义或自然switchMap 版本

关于javascript - RxJS 如何从两个 promise 中获取第一个不为空的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72036052/

相关文章:

javascript - 如何找到函数定义了多少个参数?

javascript - Firebase 管理 SDK : How to use listUsers() function as Observable combining recursive calls?

RxJS:并行执行 concatMap

javascript - Object.Assign 不创建新实例

javascript - 何时及延期

javascript - 编译时的javascript函数和var区别

angular - 函数在 debounceTime 后被多次调用

带有回调的 Angular @Output

angular - 没有可观察对象的服务

javascript - 在完成 Rxjs Observable 之前,如何等待 subscribe 中定义的异步方法?