Redux-observable返回一些样本数据

时间:2017-06-06 05:00:19

标签: redux-observable

我正在使用redux-observable,我需要将一些示例数据作为Observable返回。我的一部史诗中有以下代码

const sampleFilteredStores = Observable.of([{ type: 'FILTERED_STORES', store: 'a' }, { type: 'FILTERED_STORES', store: 'b' }]);
const filteredStores$ = action$.ofType('SEARCH_STORES').mapTo(Observable.of(sampleFilteredStores).mergeAll());
return filteredStores$;

然而,当我运行此操作时,我收到错误

instrument.js:56未捕获错误:操作必须是普通对象。使用自定义中间件进行异步操作。(...)

我在这里做错了什么,如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

研究

对于您提供的示例代码,我们需要做的第一件事是缩进并格式化代码,以便更容易理解正在发生的事情。

const somethingEpic = action => {
  const sampleFilteredStores = Observable.of([
    { type: 'FILTERED_STORES', store: 'a' },
    { type: 'FILTERED_STORES', store: 'b' }
  ]);
  const filteredStores$ = action$.ofType('SEARCH_STORES')
    .mapTo(
      Observable.of(sampleFilteredStores)
        .mergeAll()
    );

  return filteredStores$;
};

确切地说,如何格式化代码是您的选择,但我个人发现之类的更具可读性。它将帮助您调试,但也可以帮助您的代码的任何未来维护者了解您的意图。

mapTo

现在我可以立即看到一个问题,即你将一个Observable传递给mapTo,这在Rx中非常不寻常。它在100%的时间内肯定不是错误,但99.99%甚至在0.01%中都会有更明确的方式来显示所需的意图。

Observable.of

进一步深入研究,我看到Observable.of的两个用法。

第一个突出显示的是你将一个Observable传递给Observable.ofObservable.of(sampleFilteredStores)这里适用与mapTo相同的建议,这是非常罕见的,不建议使用,因为它会创建更高的顺序不必要地观察。我确实看到你使用mergeAll()来展平它,但是这会给你一个Observable,它基本上与没有间接的sampleFilteredStores相同。

当我深入挖掘时,我会注意到另一个微妙但重要的事情,就是将数组的动作传递给Observable.of。这也是高度可疑的,因为这意味着您创建一个Observable,它只发出两个动作的数组,而不是直接顺序发出这两个动作。如果后者是您的意图,则需要将对象直接作为参数传递。 Observable.of(action1, action2, action3, ...etc)。您可能会因为看到有人使用Observable.from传入数组而感到困惑,但这与Observable.of

不同

根本原因

结合这些发现我现在可以看到,这个史诗实际上发出一个Observable,而不是动作,这就是你从redux接收错误的原因。 Observable本身实际上会发出一系列动作,所以即使你把Observable弄平了,你仍然会收到相同的错误。

解决方案

看来提供的代码可能是为了简化您的问题,或者您正在学习Rx或redux-observable。但在这种特定情况下,我认为您希望收听SEARCH_STORES,并在收到时按顺序发送两个类型为FILTERED_STORES且值store不同的操作。

使用惯用的Rx,看起来像这样:

const somethingEpic = action => {
  return action$.ofType('SEARCH_STORES')
    .mergeMap(() => Observable.of(
      { type: 'FILTERED_STORES', store: 'a' },
      { type: 'FILTERED_STORES', store: 'b' }
    ))
};

此处我们正在使用mergeMap,但由于Observable.of我们在同步发布的情况下展开,我们也可以使用switchMapconcatMap相同的净效果 - 但是Observables发出异步的情况并非如此!因此,请务必研究各种扁平化策略运营商。

这个链可以描述为:每当我们收到属性type等于SEARCH_STORES的对象时,将它映射到两个对象(FILTERED_STORES动作)的Observable,它们顺序发出并且同步。

希望这有帮助!学习和使用redux-observable时要记住的一件事是,它几乎完全是"只是RxJS"恰巧是处理"动作"的对象。所以正常的,惯用的Rx是正常的惯用的redux-observable。与您可能遇到的问题相同。唯一真正的区别是redux-observable提供单ofType运算符作为filter的简写(正如文档描述的那样)。如果您将来遇到Rx问题,您可能会发现重构示例以使用filter并将它们与redux-observable无关,因为Rx社区显然要大得多!