Estoy tratando de entender cómo funciona RxJS concat y cómo funciona con Promises en general.
Tengo dos observables:
currentConfirmation$ emite nulo
newConfirmation$ emite una nueva confirmación
Podría alguien explicar por qué esto funciona:
const finalConfirmation$ = currentConfirmation$.pipe( switchMap((conf) => { if (!conf) { return newConfirmation$ } return of(conf) }) )Pero esto no
const finalConfirmation$ = concat(currentConfirmation$, newConfirmation$).pipe(find((conf) => !!conf)) Por no funciona quiero decir que esta prueba pasa con la versión switchMap y se agota con la versión 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() }) })También me encantaría saber si hay un mejor enfoque para lograr lo anterior que el que se me ocurrió.
Editar: Aquí está todo el código relevante para la prueba:
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 solo ejecuta cada observable pasado y devuelve cada uno de ellos secuencialmente, y no muta nada en el medio ni proporciona ningún otro medio para agregar comprobaciones condicionales.
Puedo ver su ejemplo usando find that hack the way through, ya que completa la transmisión cuando se cumple la condición dada, pero probablemente no sea tan semántico o natural como la versión switchMap