在redux-observable

时间:2016-10-26 21:31:49

标签: javascript redux action rxjs redux-observable

我正在尝试评估redux-observable。只是查看文档,我正试图让异步史诗加载的事情发生。我从docs创建了一个jsbin的fork,它基本上试图添加BehaviorSubject东西的异步使用。

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

在“PING PONG”示例中,我添加了“OTHER”操作,然后使用BehaviorSubject.next(如文档中所述)添加该epic。但是,当我运行这个例子时,会发生什么事情是PING动作被触发,然后是无休止的'OTHER'动作,但从来没有PONG动作。为了看到这个,我添加了reduxLogger。在开发工具控制台中查看它,因为jsbin控制台无法正确呈现它。

我的问题是我做错了什么?为什么PONG动作永远不会被派遣?

1 个答案:

答案 0 :(得分:4)

您的otherEpic是一个无限的“循环”(随着时间的推移)

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

此史诗的行为是“当接收到任何动作时,等待1000毫秒,然后发出另一个OTHER类型的动作”。而且,由于你的Epics发出的动作像其他任何动作一样经过正常的store.dispatch周期,这意味着在收到第一个PING之后,它会在1000ms后发出OTHER,然后再次被相同的史诗递归接收,等待另一个1000毫秒并发出另一个 OTHER,永远重复。

我不确定这是否已知,但想指出它。

在rootEpic开始运行/已订阅之前,您next()进入epic$的BehaviorSubject。

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

在具有异步/捆绑拆分的实际应用程序中,当您调用epic$.next(newEpic)时,总是在中间件订阅了您的rootEpic并收到您提供给您的{的初始史诗后{1}}。

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

BehaviorSubject

文档在示例中说“稍后”,我现在看到的不够清楚。我会尝试进一步澄清这一点。

如果您将反应路由器与Webpack的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); 拆分一起使用,您可能会发现this other question on async loading of Epics非常有用。

如果我能进一步澄清其中任何一项,请告诉我