【问题标题】:How to make redux-observable send multiple actions before and after ajax request?如何使 redux-observable 在 ajax 请求之前和之后发送多个操作?
【发布时间】:2018-02-06 04:57:36
【问题描述】:

我正在尝试为 redux-observable 编写 Epic。但我有一个问题(

ON_EMPTY_FORM_STATE 动作在.map(response => formSavedAction(response)) 执行之前执行。

我该如何解决?基本上我想要得到的是:

  1. 捕获FORM_SEND 动作
  2. 发送带有负载的 Ajax 请求
  3. 如果我从服务器收到 200 响应然后执行formSavedAction(response)
  4. 如果我收到 500 错误然后发送 { type: ON_FORM_SUBMIT_ERROR }
  5. 最后(无论返回什么 Ajax 请求)我要调度操作{ type: EMPTY_FORM_STATE }

这是我的代码:

const saveProductEpic = (action$, $store) =>
action$.ofType(SUBMIT_FORM)
    .mergeMap(action => ajax.post('http://localhost:9000/products', action.payload,
        { 'Content-Type': 'application/json' }))
    .map(response => formSavedAction(response))
    .catch(err => { $store.dispatch({ type: ON_FORM_SUBMIT_ERROR }) })
    .do(() => { $store.dispatch({ type: EMPTY_FORM_STATE }) })

问题是动作{ type: EMPTY_FORM_STATE } 被调度之前 而不是在 AJAX 请求之后。

有没有办法解决这个问题?

【问题讨论】:

  • 只需删除.do 块并将$store.dispatch({ type: EMPTY_FORM_STATE }) 添加到.then.catch 两个案例中
  • 不工作....我收到错误 TypeError: action$.ofType(...).mergeMap(...).map(...).then is not a function
  • 我能知道你为什么在代码中使用.map 而不是.then 吗?以及您使用什么 http 库?
  • 如果我使用 .then 而不是 .map 会有什么不同吗?我正在使用 RX.Dom.Ajax

标签: javascript reactjs rxjs redux-observable


【解决方案1】:

redux-observable 的工作方式是在中间件中订阅了史诗函数返回的 observable。您的 observable 必须发出 redux 操作,因为 subscribe 函数只是:action => store.dispatch(action)

因为您在史诗中直接使用 store.dispatch,所以您正在规避 redux-observable 并按照您的预期分派事情。

要按照您期望的顺序发出动作,您可以这样做:

action$.ofType(SUBMIT_FORM)
  .mergeMap(action => ajax.post('http://localhost:9000/products', action.payload,
    { 'Content-Type': 'application/json' }))
  .map(response => formSavedAction(response))
  // Notice that catch is now returning the value by dropping the brackets.
  .catch(err => Observable.of({ type: ON_FORM_SUBMIT_ERROR }))
  // send whatever action has come through, and add the empty state action after it.
  .mergeMap(action => Observable.of(action, { type: EMPTY_FORM_STATE }))

概念演示:https://jsbin.com/focujikuse/edit?js,console

【讨论】:

  • 是--请不要使用store.dispatch github.com/redux-observable/redux-observable/issues/314
  • 我试图用你的方式处理史诗,但发生了一些奇怪的事情。它看起来像动作 .map(response => formSavedAction(response)) 和 mergeMap(action => Rx.Observable。 from(action$, { type: ON_EMPTY_FORM_STATE })) 根本不会执行...我在减速器中添加了一些日志记录,它完全没有显示任何内容。
  • 修复了上一次mergeMap中的一个错误;需要用的,不能从的。尝试使用 .do(console.log) 语句登录史诗。如果它没有通过 ajax 请求,则可能存在问题。
【解决方案2】:
const saveProductEpic = (action$, $store) => action$.ofType(SUBMIT_FORM)
.mergeMap((data) => Rx.Observable.concat(
    ajax.post(url, data.payload, params).mergeMap(
        (response) => Rx.Observable.of(formSavedAction(response)) )
        .catch(err => { $store.dispatch({ type: ON_FORM_SUBMIT_ERROR }) }),
    Rx.Observable.of({ type: ON_EMPTY_FORM_STATE })
    .delay(2000)
));

【讨论】:

    【解决方案3】:

    const saveProductEpic = (action$, $store) => action$.ofType(SUBMIT_FORM) .mergeMap(action => ajax.post('http://localhost:9000/products',action.payload, { 'Content-Type': 'application/json' }) .mergeMap(response => Observable.of(formSavedAction(response), emptyFormStateAction())) .catch(err => Observable.of( formSubmitErrorAction(), emptyFormStateAction()) ) );

    其中 emptyFormStateAction 和 formSubmitErrorAction 是动作创建者。

    【讨论】:

      猜你喜欢
      • 2022-01-27
      • 2020-12-29
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 1970-01-01
      • 2011-03-19
      • 2018-10-14
      • 1970-01-01
      相关资源
      最近更新 更多