简体   繁体   English

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

[英]asynchronously add epic to middleware in redux-observable

I'm trying to evaluate redux-observable. 我正在尝试评估redux-observable。 Just looking through the doc and I'm trying to get the async epic loading thing going. 只是查看文档,我正在尝试使异步史诗加载过程继续进行。 I created a fork of the jsbin from the docs which basically attempts to add the async usage of the BehaviorSubject stuff. 我从文档创建了一个jsbin的fork,它基本上试图添加BehaviorSubject东西的异步用法。

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

In that 'PING PONG' example, I added an 'OTHER' action and then use BehaviorSubject.next (as described in the docs) to add that epic. 在该“ PING PONG”示例中,我添加了一个“ OTHER”操作,然后使用BehaviorSubject.next(如文档中所述)添加该史诗。 However, when I run the example, what happens is that the PING action is fired, followed by an endless stream of 'OTHER' actions, but never the PONG action. 但是,当我运行该示例时,发生的是触发了PING动作,随后是无尽的“ OTHER”动作流,但从未触发PONG动作。 To see this, I added the reduxLogger. 为了看到这一点,我添加了reduxLogger。 View it in the dev tools console as the jsbin console doesn't render it correctly. 由于jsbin控制台无法正确呈现它,因此请在开发工具控制台中查看它。

My question is what am I doing wrong? 我的问题是我做错了什么? Why does the PONG action never get dispatched? 为什么永远不会派出PONG动作?

Your otherEpic is an infinite "loop" (over time) 您的otherEpic是无限的“循环”(随着时间的流逝)

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

This epic has the behavior "when any action at all is received, wait 1000ms and then emit another action of type OTHER ". 这部史诗具有行为“收到所有的任何行动时,等待1000毫秒,然后发出型的另一个动作OTHER ”。 And since the actions your Epics emit go through the normal store.dispatch cycle like any other action, that means after the first PING is received, it will emit an OTHER after 1000ms, which will then be recursively received by the same epic again, wait another 1000ms and emit another OTHER , repeat forever. 并且由于您的Epics发出的动作像其他任何动作一样经过正常的store.dispatch周期,这意味着在收到第一个PING之后,它将在1000ms之后发出OTHER ,然后由同一史诗再次递归接收,请等待再发射1000毫秒并发射另一个 OTHER ,直到永远重复一次。

I'm not sure if this was known, but wanted to point it out. 我不确定是否知道这一点,但想指出。

You next() into the BehaviorSubject of epic$ before your rootEpic has started running/been subscribed to it. 您可以在rootEpic开始运行/对其进行预订之前,将next()插入epic$的BehaviorSubject中。

BehaviorSubjects will keep the last value emitted and provide that immediately when someone subscribes. BehaviorSubjects将保留最后发出的值,并在有人订阅时立即提供。 Since your rootEpic has not yet been called and subscribed to the by the middleware, you're replacing the initial value, so only the otherEpic is emitted and ran through the epic$.mergeMap stuff. 由于您的rootEpic尚未被中间件调用和预订,因此您将替换初始值,因此仅发出otherEpic并通过epic$.mergeMap东西运行。

In a real application with async/bundle splitting, when you would call epic$.next(newEpic) should always be after the middleware has subscribed to your rootEpic and received the initial epic you provided to your BehaviorSubject . 在具有异步/捆绑拆分的实际应用程序中,何时调用epic$.next(newEpic)应该始终在中间件订阅了rootEpic并收到您提供给BehaviorSubject的初始事件之后。

Here's a demo of that working: http://jsbin.com/zaniviz/edit?js,output 这是工作原理的演示: http : //jsbin.com/zaniviz/edit?js,输出

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);

The documentation says "sometime later" in the example, which I now see isn't clear enough. 文档在示例中说“稍后再说”,我现在还不太清楚。 I'll try and clarify this further. 我将尝试进一步澄清。


You may also find this other question on async loading of Epics useful if you're using react-router with Webpack's require.enquire() splitting. 如果您使用带有Webpack的require.enquire()拆分的react-router,则可能还会发现关于Epics的异步加载的另一个问题很有用。

Let me know if I can clarify any of these further 🖖 让我知道是否可以进一步澄清这些问题🖖

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM