1

我有这个redux-observable史诗,它将POSTjson 主体发送到我的后端,但它实际上从来没有发送实际的网络请求。它使用Rx.DOM.Request.post(url, [body])(我想?请查看我的导入以确认)。我可以验证网络请求永远不会离开我的应用程序,更不用说到达我的后端了:

import { Observable } from 'rxjs'
import 'redux-observable'
import {
  UPLOAD_IMAGE,
  UPLOAD_IMAGE_FULFILLED,
  UPLOAD_IMAGE_REJECTED,
  UPLOAD_PRODUCT,
  uploadImageFulfilled,
  uploadImageRejected,
  uploadProductFulfilled,
  uploadProductRejected
} from './addForm.action'
import {
  updateAlertModalIsOpen,
  updateAlertModalMessage,
  updateAlertModalTitle
} from '../alert-modal/alertModal.action'
import 'rxjs/add/operator/catch'
import { RNS3 } from 'react-native-aws3'
import { ajax } from 'rxjs/observable/dom/ajax'

export const uploadProductEpic = action$ =>
  action$.ofType(UPLOAD_PRODUCT)
    .mergeMap(action => {
      ajax.post(
        'http://192.168.20.3:4000/products', 
        action.payload,
        { 'Content-Type': 'application/json' })
    })
    .map(response => uploadProductFulfilled(response))
    .catch(error => Observable.of(uploadProductRejected(error)))

它通过按下按钮来调用:

      onPress={() => {
       let product = {
              "name": props.name,
              "brand": props.brand,
              "description": props.description,
              "image": "fakeUrl"
          }

        props.uploadProduct(JSON.stringify(product))

这是action上述史诗中对象的内容:

payload: "{"name":"v","brand":"v","description":"v","image":"fakeUrl"}"
type: "UPLOAD_PRODUCT"

是因为我的 json 使用了所有没有转义的双引号吗?

我可以验证在按下按钮时执行 ajax 帖子的史诗中的代码行确实运行,并且在第一个按钮按下时它最终调度uploadProductRejected(error),甚至没有发出网络请求,以及在哪里调度错误uploadProductRejected动作是公正的{ },并且在随后的按钮按下时,它甚至不会发送拒绝或已完成的动作。

知道为什么它被拒绝,为什么它甚至从未尝试发出网络请求吗?

4

1 回答 1

6

顺便说一句-您指向的文档适用Rx.DOM.Request于 RxJS 的 v4,但您的代码使用的是 v5。v5 的文档位于此处,但遗憾的Observable.ajax尚未记录,但它非常接近 v4 版本并且具有最明显的 API。


关于您的代码,我们首先需要做几件事。

您可能不应该将mapandcatch放在顶级 Observable 上。如果这样做,mergeMap则允许您内部的任何错误传播并action$.ofType到达Observable.of(uploadProductRejected(error)).

相反,您希望通过将该逻辑放在以下内容中来隔离您的 Observable mergeMap

export const uploadProductEpic = action$ =>
  action$.ofType(UPLOAD_PRODUCT)
    .mergeMap(action => {
      ajax.post(
        'http://192.168.20.3:4000/products', 
        action.payload,
        { 'Content-Type': 'application/json' }
      )
        .map(response => uploadProductFulfilled(response))
        .catch(error => Observable.of(uploadProductRejected(error)))
    });

虽然这只是普通的 RxJS,但在 redux-observable 中这尤其重要,因为您不希望您的史诗在一个请求失败时终止。这在此处的文档中进行了描述。如果这令人困惑,我建议花一些时间来完全理解 Observable 链是如何工作的。除了阅读文档和教程(很有帮助)之外,还可以尝试像 jsbin 这样的 REPL。


既然我们已经解决了这个问题,要真正解决您的问题,您需要查看您捕获并发出的实际错误消息是什么uploadProductRejected()

尽管您没有提供它,但我可以根据您的代码猜测它类似于:

TypeError:您在预期流的位置提供了“未定义”。您可以提供 Observable、Promise、Array 或 Iterable。在 subscribeToResult

它还将包括一个堆栈跟踪,它应该首先指向类似的东西MergeMapSubscriber._innerSub,这意味着它mergeMap是引发此错误的操作员。如果我们查看您的使用情况,mergeMap我们可以看到实际上我们没有返回任何东西!由于您使用的是带有花括号的箭头函数,这意味着您需要有一个明确的return.

export const uploadProductEpic = action$ =>
  action$.ofType(UPLOAD_PRODUCT)
    .mergeMap(action => { // <--------------------------- whoops!
      ajax.post(
        'http://192.168.20.3:4000/products', 
        action.payload,
        { 'Content-Type': 'application/json' })
    })

您可能打算使用不带花括号的箭头函数,以便它具有隐式返回。

于 2017-05-23T00:03:54.007 回答