最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to create an redux-observable epic that waits for 2 actions before doing anything - Stack Overflow

programmeradmin6浏览0评论

I would like to create an epic that listens for a explicit sequence of actions before doing work.

This epic also does not need to exist after it pletes the first time.

I'm picturing something like:

function doTheThing(action$) {
  return action$
     // The start of the sequence
    .ofType(FIRST_ACTION)

    // Do nothing until the second action occurs
    .waitForAnotherAction(SECOND_ACTION)

    // the correct actions have been dispatched, do the thing!
    .map(() => ({ type: DO_THE_THING_ACTION }))
    .destroyEpic();
}

Is something like this possible with redux-observable?

I would like to create an epic that listens for a explicit sequence of actions before doing work.

This epic also does not need to exist after it pletes the first time.

I'm picturing something like:

function doTheThing(action$) {
  return action$
     // The start of the sequence
    .ofType(FIRST_ACTION)

    // Do nothing until the second action occurs
    .waitForAnotherAction(SECOND_ACTION)

    // the correct actions have been dispatched, do the thing!
    .map(() => ({ type: DO_THE_THING_ACTION }))
    .destroyEpic();
}

Is something like this possible with redux-observable?

Share Improve this question edited Jul 11, 2017 at 23:28 Danny Delott asked Jul 11, 2017 at 23:05 Danny DelottDanny Delott 7,0184 gold badges38 silver badges58 bronze badges 7
  • 2 FYI nearly all redux-observable "how do I" questions are actually just RxJS questions where the data flowing just happens to be actions, but that's not super relevant. – jayphelps Commented Jul 11, 2017 at 23:18
  • Yep, thanks for the reminder. Added the rxjs tag. – Danny Delott Commented Jul 11, 2017 at 23:19
  • 1 do you need access to the first action's payload? how bout the second one? – jayphelps Commented Jul 11, 2017 at 23:20
  • Nope, neither payload is used. – Danny Delott Commented Jul 11, 2017 at 23:26
  • Seems like an odd pattern IMO. I would personally put that sort of state in redux itself and no need for epics to be involved – jayphelps Commented Jul 11, 2017 at 23:31
 |  Show 2 more ments

2 Answers 2

Reset to default 6

As @jayphelps pointed out in the ments there are a couple variants depending on whether you need access to the various events and if the events must be strictly ordered. So the following should all fit:

1) Strictly ordered don't care about events:

action$
  .ofType(FIRST_ACTION)
  .take(1)
  .concat(action$.ofType(SECOND_ACTION).take(1))
  .mapTo({ type: DO_THE_THING_ACTION })

2) Strictly ordered do care about events

action$
  .ofType(FIRST_ACTION)
  .take(1)
  .concatMap(
    a1 => action$.ofType(SECOND_ACTION).take(1),
    (a1, a2) => ({type: DO_THE_THING_ACTION, a1, a2})
  )

3) Non-strictly ordered (do or don't) care about events

Observable.forkJoin(
  action$.ofType(FIRST_ACTION).take(1),
  action$.ofType(SECOND_ACTION).take(1),
  // Add this lambda if you *do* care
  (a1, a2) => ({type: DO_THE_THING_ACTION, a1, a2})
)
// Use mapTo if you *don't* care
.mapTo({type: DO_THE_THING_ACTION})

This is how it looks with redux observables:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/zip';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';


function doTheThing(action$) {
  return Observable
     // waits for all actions listed to plete
    .zip(action$.ofType(FIRST_ACTION).take(1), 
         action$.ofType(SECOND_ACTION).take(1),
     )

    // do the thing
    .map(() => ({ type: DO_THE_THING_ACTION }));
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论