Redux Observable: если одно и то же действие отправляется несколько раз, как мне отменить одно из них?

Скажем, у меня есть вот такая эпопея:

export const getUserEpic = action$ => action$
  .ofType(t.GET_USER)
  .mergeMap(action => Observable
    .from(query.findUser(action.uid))
    .map(user => ({ type: t.GET_USER_SUCCESS, user }))
    .takeUntil(action$.ofType(t.GET_USER_CANCELLED))

Затем где-то я отправил t.GET_USER несколько раз:

dispatch({ type: t.GET_USER, uid: 'uid1' })
dispatch({ type: t.GET_USER, uid: 'uid2' })
dispatch({ type: t.GET_USER, uid: 'uid3' })

Как отменить один из них? Например:

dispatch({ type: t.GET_USER_CANCELLED, uid: 'uid2' })

Насколько я знаю, .takeUntil(action$.ofType(t.GET_USER_CANCELLED)) отменит все t.GET_USER действия. Мне нужно отменить только один.


person Jaye Renzo Montejo    schedule 28.11.2017    source источник
comment
Вы можете использовать switchMap вместо mergeMap, но это действительно зависит от логики вашего приложения.   -  person martin    schedule 28.11.2017


Ответы (1)


Вы можете использовать предикат .filter(), чтобы отказаться от подписки на вашу карту слияния только для того uid, который вы ищете:

export const getUserEpic = action$ => action$
  .ofType(t.GET_USER)
  .mergeMap(action => Observable
    .from(query.findUser(action.uid))
    .map(user => ({ type: t.GET_USER_SUCCESS, user }))
    .takeUntil(
      action$
        .ofType(t.GET_USER_CANCELLED)
        .filter(act => act.uid === action.uid)
    )
person Mark van Straten    schedule 28.11.2017
comment
Это абсолютно блестяще. Большое спасибо. - person Jaye Renzo Montejo; 28.11.2017