Weird `Uncaught TypeError: unknown type returned` while returning an stream from `Observable.fromNodeCallback`

Weird `Uncaught TypeError: unknown type returned` while returning an stream from `Observable.fromNodeCallback`

据我目前了解,epic 的模式是 "actions in, actions out"。

我使用MeteorJS,需要遵循调用Meteor方法与服务器交互的约定。

看起来像这样:

Meteor.call("<function-name>", ...args, callback)

所以我尝试像这样处理史诗的异步副作用:

completedSubscribe is just an action creator: const completedSubscribe = result => {type: SUCCEED, result}

import { Observable } from 'rx'

const fromMeteorCall = Observable.fromNodeCallback(Meteor.call)
const subscriptionsEpic = action$ =>
    action$.ofType(REQUEST_SUBSCRIBE)
        .mergeMap(action => {
            const call$ = fromMeteorCall('subscriptions.insert', action.email)
            return call$.map(completedSubscribe)
        })

然后我得到错误:Uncaught TypeError: unknown type returned

为确保我实际执行 return 操作,

我试着打电话订阅:

call$.subscribe(
  function (x) { console.log('onNext: success!'); },
  function (e) { console.log('onError: %s', e); },
  function ()  { console.log('onCompleted'); }
);

然后订阅就完美了,

但 Epic 仍然无法工作并继续抛出 Uncaught TypeError: unknown type returned

我觉得可能不是MeteorJS的方法问题, 这可能发生在从回调创建的其他可观察对象中。

也许我误解了 redux-observablerxjs, 任何意见都会很有帮助。

您收到的错误来自 mergeMap,它没有收到它可以识别的内容。问题是您正在尝试使用 RxJS v4,而不是 v5,redux-observable。因此,虽然这可能令人困惑,但我将尝试解释发生了什么:

你尝试 return v4 Observable 到 v5 mergeMap,这就是它失败的原因。您的 action$.ofType().mergeMap() 代码来自 RxJS v5,因为这是 redux-observables 默认使用的代码,并且 mergeMapflatMap 在 v5 中被调用,但在 v4 中没有)。然后你import rx 就是v4的包名(v5目前发布在rxjs下,注意js后缀)。在 v5 中 fromNodeCallback 被重命名为 bindNodeCallback,所以这再次确认这是 v4.

为了解决这个问题,我建议您删除 v4 并改为 use v5 entirely. However if you do in fact need to use v4, we have an adapter for redux-observable you will need to install and use redux-observable-adapter-rxjs-v4。如果你使用它,提供给你的史诗的 action$ observable 现在将是 v4 Observable,这意味着你需要将 mergeMap 更改为 flatMap(并且两者之间还有其他细微差别两个)。