从其他史诗中调用史诗

时间:2017-02-16 14:14:34

标签: reactjs redux rxjs redux-observable

首先为这个真棒图书馆提供许多道具!我仍然在努力使用一个用例。我想首先打电话给另一部史诗并等到它完成然后继续当前的史诗。假设我有一个用户可以更改内容的表单。在将其他数据加载到表单之前,我想先保存当前的更改。有什么想法吗?

2 个答案:

答案 0 :(得分:6)

听起来像你想要的:如果一部史诗想要开启另一部史诗作品 在继续之前等待它完成。

一种方法是(使用伪名称),当收到初始操作LOAD_OTHER_DATA时,您立即开始侦听单个SAVE_FORM_FULFILLED,这表示该表单已保存(我们将启动它在一点点)。收到后,我们mergeMap(或switchMap,在这种情况下并不重要)我们调用加载其他数据loadOtherDataSomehow()并执行常规业务。最后,开始实际保存我们正在等待的表单的技巧是在整个链的末尾添加一个startWith() - 它将发出并发送动作以实际保存表单。

const saveFormEpic = (action$, store) =>
  action$
    .ofType('SAVE_FORM')
    .switchMap(() =>
      saveFormSomeHow(store.getState().formDataSomewhere)
        .map(details => ({
          type: 'SAVE_FORM_FULFILLED'
        }))
    );

const loadOtherDataEpic = action$ =>
  action$
    .ofType('LOAD_OTHER_DATA')
    .switchMap(() =>
      action$.ofType('SAVE_FORM_FULFILLED')
        .take(1) // don't listen forever! IMPORTANT!
        .mergeMap(() =>
          loadOtherDataSomeHow()
            .map(otherData => ({
              type: 'LOAD_OTHER_DATA_FULFILLED',
              payload: otherData
            }))
        )
        .startWith({
          type: 'SAVE_FORM'
        })
    );

你没有提到你的加载和保存是如何工作的,所以这只是伪代码,你需要根据你的用例进行修改。

答案 1 :(得分:0)

@jayphelps,我只是想说谢谢你所回答的所有问题,他们真的帮助我解决了很多问题。

我试图制定我的问题,发现你已经在这里回答了问题并设法使用你的样本来解决我的问题。

我的例子有/我有2个expics,我希望/ ed彼此调用:

const requestNameEpic = action$ =>
  action$.ofType("REQUEST_NAME")
    .switchMap(({id}) =>
      Observable.of(`name returned by 'ajax' call, using id: ${id}`) // Ajax simulation
        .delay(1000)
        .map(name => ({type: "LOAD_NAME", name}))
    );

const requestAgeEpic = action$ =>
  action$.ofType("REQUEST_AGE")
    .switchMap(({name}) =>
      Observable.of(`age returned by 'ajax' call, using name: [${name}]`)
        .delay(1000)
        .map(age => ({type: "LOAD_AGE", age}))
    );

我设法解决它的方法是使用:

const requestDetailsEpic = action$ =>
  action$.ofType("LOAD_NAME")
    .map(({name}) => ({type: "REQUEST_AGE", name}));

因此,调度REQUEST_NAME也会调度REQUEST_AGE,但之后我永远无法调度LOAD_NAME。

我重构了你的样本:

const requestDetailsEpic = action$ =>
  action$.ofType("REQUEST_DETAILS")
    .switchMap(({id}) =>
      action$.ofType("LOAD_NAME")
        .take(1) // don't listen forever! IMPORTANT!
        .map(({name}) => ({type: "REQUEST_AGE", name}))
        .startWith({type: "REQUEST_NAME", id})
  );

再次感谢您在redux-observable和所有社区支持方面所做的所有出色工作。