0

我正在尝试评估 redux-observable。只是查看文档,我正在尝试进行异步史诗加载。我从文档中创建了一个 jsbin 的分支,它基本上试图添加 BehaviorSubject 东西的异步使用。

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

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

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

4

1 回答 1

4

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

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

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

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

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

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

在具有异步/捆绑拆分的实际应用程序中,您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);

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


如果您将 react-router 与 Webpack 的拆分一起使用,您可能还会发现关于 Epics 异步加载的其他问题很有用。require.enquire()

让我知道我是否可以进一步澄清这些

于 2016-10-27T01:54:23.990 回答