我有redux-observable史诗,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帖子的epic中的代码行,按下它的第一个按钮结束调度uploadProductRejected(error)
,甚至没有发出网络请求,并且在uploadProductRejected
操作中调度的错误仅为{ }
,并且在后续按钮按下时,它甚至不会调度拒绝或已完成的操作。
知道它被拒绝的原因,以及为什么它甚至都没有尝试发出网络请求?
答案 0 :(得分:6)
btw - 您为Rx.DOM.Request
指向的文档适用于RxJS的v4,但您的代码使用的是v5。 v5的文档为located here,但遗憾的是Observable.ajax
为not yet documented,但它与v4版本非常接近,并且有一个非常明显的API。
关于你的代码,我们首先要做几件家务事。
您可能不应将map
和catch
置于顶级Observable之外。如果您这样做,mergeMap
内的任何错误都会被传播出去并到达action$.ofType
,这意味着您的epic将会终止,因为您捕获了错误,而是从错误的顶级链切换到{ {1}}。
相反,您希望通过将该逻辑置于Observable.of(uploadProductRejected(error))
内来隔离您的Observable:
mergeMap
虽然这只是普通的RxJS,但在redux-observable中这一点尤其重要,因为你不希望你的史诗在一个请求失败时终止。这被描述为in the docs here。如果这令人困惑,我建议花些时间充分了解Observable链的工作原理。除了阅读文档和教程(有用)之外,还可以像jsbin一样在REPL中进行实验。
现在我们已经完成了这个问题,要真正解决您的问题,您需要查看您捕获并发出的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)))
});
实际错误消息。
虽然你没有提供它,但我可以根据你的代码猜测它是这样的:
TypeError:您提供了“未定义”,其中包含预期的流。您可以提供Observable,Promise,Array或Iterable。在subscribeToResult
它还包括一个堆栈跟踪,它应该首先指向类似uploadProductRejected()
的东西,这意味着它是MergeMapSubscriber._innerSub
运算符抛出此错误。如果我们查看您对mergeMap
的使用情况,我们可以看到实际上我们没有返回任何内容!由于你使用带有花括号的箭头功能,这意味着你需要有一个明确的mergeMap
。
return
你可能想要使用没有花括号的箭头函数,因此它有一个隐式返回。