我有这个可观察的史诗,它POST
我的后端是一个 json 体,但它实际上从未达到发送实际网络请求的程度。它使用 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 post 的史诗中的代码行在按下按钮时确实运行,并且在按下第一个按钮时它最终会调度uploadProductRejected(error)
,甚至没有发出网络请求,并且在uploadProductRejected
操作中调度的错误只是{ }
,在随后按下按钮时,它甚至从未调度被拒绝或完成的操作。
知道为什么它被拒绝,为什么它甚至从不尝试发出网络请求吗?
顺便说一句 - 你指向Rx.DOM.Request
的文档是针对RxJS的v4的,但你的代码使用的是v5。v5 的文档位于此处,但不幸的是Observable.ajax
尚未记录,但它非常接近 v4 版本,并且具有最明显的 API。
关于您的代码,我们需要先做几件内务管理工作。
您可能不应该将map
和catch
放在顶层可观察对象上。如果你这样做,你的mergeMap
内的任何错误都被允许传播出去并到达action$.ofType
,这意味着你的史诗将终止,因为你抓住了错误,而是从出错的顶级链切换到Observable.of(uploadProductRejected(error))
。
相反,您希望通过将逻辑放在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 中,这一点尤其重要,因为您不希望您的 epic 在一个请求失败时终止。此处的文档对此进行了描述。如果这令人困惑,我建议花一些时间来充分理解可观察链的工作原理。除了阅读文档和教程(很有帮助)之外,还可以在像jsbin这样的REPL中进行实验。
现在我们已经解决了这个问题,要真正解决您的问题,您需要查看您捕获并发出的实际错误消息是什么uploadProductRejected()
.
虽然你没有提供它,但我可以根据你的代码猜测它是这样的:
类型错误:您在需要流的位置提供了"未定义"。您可以提供可观察、承诺、数组或可迭代。在订阅到结果
它还将包括一个堆栈跟踪,它应该首先指向类似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' })
})
您可能打算使用不带大括号的箭头函数,以便它具有隐式返回。