在 redux-observable 中将史诗异步添加到中间件

asynchronously add epic to middleware in redux-observable

我正在尝试评估 redux-observable。只是浏览文档,我正试图让异步史诗般的加载事情继续下去。我从文档创建了一个 jsbin 的分支,它基本上试图添加 BehaviorSubject 东西的异步用法。

http://jsbin.com/bazoqemiqu/edit?html,js,output

在那个 'PING PONG' 示例中,我添加了一个 'OTHER' 操作,然后使用 BehaviorSubject.next(如文档中所述)添加该史诗。然而,当我 运行 这个例子时,发生的是 PING 动作被触发,然后是无穷无尽的 'OTHER' 动作流,但从来没有 PONG 动作。为了看到这一点,我添加了 reduxLogger。在开发工具控制台中查看它,因为 jsbin 控制台无法正确呈现它。

我的问题是我做错了什么?为什么 PONG 操作永远不会被调度?

你的otherEpic是无限的"loop"(随着时间的推移)

const otherEpic$ = action$ => 
  action$
    .delay(1000)
    .mapTo({ type: OTHER });

此史诗具有行为 "when any action at all is received, wait 1000ms and then emit another action of type OTHER"。由于你的 Epics 发出的动作像任何其他动作一样经历正常的 store.dispatch 循环,这意味着在收到第一个 PING 后,它将在 1000 毫秒后发出 OTHER ,然后将再次被同一史诗递归接收,再等待 1000 毫秒并发出 另一个 OTHER,永远重复。

我不确定这是否为人所知,但想指出来。

next() 在您的 rootEpic 开始之前 next() 进入了 epic$ 的 BehaviorSubject running/been 订阅了它。

BehaviorSubjects 将保留发出的 last 值,并在有人订阅时立即提供该值。由于您的 rootEpic 尚未被中间件调用和订阅,因此您要替换 initial 值,因此仅发出 otherEpic 和 运行通过 epic$.mergeMap 东西。

在具有 async/bundle 拆分的真实应用程序中,当您调用 epic$.next(newEpic) 时,应该 总是 在中间件订阅了您的 rootEpic 并收到您提供给 BehaviorSubject.

的初始史诗

这是该工作的演示:http://jsbin.com/zaniviz/edit?js,output

const epic$ = new BehaviorSubject(combineEpics(epic1, epic2, ...etc));
const rootEpic = (action$, store) =>
  epic$.mergeMap(epic => {console.log(epic)
    return epic(action$, store)
  });

const otherEpic = action$ =>
  action$.ofType(PONG)
    .delay(1000)
    .mapTo({ type: OTHER });

const epicMiddleware = createEpicMiddleware(rootEpic);
const store = createStore(rootReducer,
  applyMiddleware(loggerMiddleware, epicMiddleware)
);

// any time AFTER the epicMiddleware
// has received the rootEpic
epic$.next(otherEpic);

文档在示例中说 "sometime later",我现在看不够清楚。我会尝试进一步澄清这一点。


如果您将 react-router 与 Webpack 的 require.enquire() 拆分一起使用,您可能还会发现 很有用。

如果我可以进一步澄清这些问题,请告诉我