使用Redux可观察的史诗通过多个动作来装饰数据

里斯托

我在努力工作redux-observable,试图弄清楚如何用此流程创建史诗:

  1. 听一个GET_ITEMS_REQUEST动作
  2. 发送HTTP请求以获取一些物品
  3. 抓取这些项目的ID并调度一个GET_ITEM_DETAILS_REQUEST操作,该操作将发送另一个HTTP请求以获取这些项目的更多详细信息
  4. 用第二个请求的详细信息装饰第一个请求的项目,并分派最终GET_ITEMS_SUCCESS操作,这将更新redux状态

从第3步到第4步是我遇到的问题。我知道如何GET_ITEM_DETAILS_REQUEST使用商品ID进行分派,但是我不知道如何监听/订阅GET_ITEM_DETAILS_REQUEST操作以获取商品详细信息响应。

到目前为止,我有以下内容:

function getItemsEpic(action$) {

  return action$
    // step 1
    .ofType('GET_ITEMS_REQUEST')
    .mergeMap(() => {
      // step 2
      return Observable.from(Api.getItems())
    })
    .mergeMap((items) => {
      // step 3
      const itemIds = items.map((item) => item.id);
      return Observable.of({
        type: 'GET_ITEM_DETAILS_REQUEST',
        ids: itemIds
      });
    })
    // ... what now?
    .catch(() => {
      return Observable.of({
        type: 'GET_ITEMS_FAILURE'
      });
    });
}
Jayphelps

一种方法是,在收到项目后,开始收听GET_ITEM_DETAILS_FULFILLED,然后立即GET_ITEM_DETAILS_REQUEST使用开始startWith()另一部史诗将查找详​​细信息并发出GET_ITEM_DETAILS_FULFILLED我们的另一部史诗正在耐心等待的内容,然后将这两个(项目+细节)压缩在一起。

const getItemDetailsEpic = action$ =>
  action$
    .ofType('GET_ITEM_DETAILS_REQUEST')
    .mergeMap(({ ids }) =>
      Observable.from(Api.getItemDetails(ids))
        .map(details => ({
          type: 'GET_ITEM_DETAILS_FULFILLED',
          details
        }))
    );

const getItemsEpic = action$ =>
  action$
    .ofType('GET_ITEMS_REQUEST')
    .mergeMap(() =>
      Observable.from(Api.getItems())
        .mergeMap(items =>
          action$.ofType('GET_ITEM_DETAILS_FULFILLED')
            .take(1) // don't listen forever! IMPORTANT!
            .map(({ details }) => ({
              type: 'GET_ITEMS_SUCCESS',
              items: items.map((item, i) => ({
                ...item,
                detail: details[i]
                // or the more "safe" `details.find(detail => detail.id === item.id)`
                // if your data structure allows. Might not be necessary if the
                // order is guaranteed to be the same
              }))
            }))
            .startWith({
              type: 'GET_ITEM_DETAILS_REQUEST',
              ids: items.map(item => item.id)
            })
        )
    );

另外,我注意到您将您catch()放在可观察的外部链上。这可能不会完全完成您想要的操作。当错误到达最上层链时,您的整个史诗将被终止,它将不再监听未来GET_ITEMS_REQUEST这是一个非常重要的区别,我们通常称其为“隔离您的可观察链”。您不希望错误传播得比其应有的程度更大。

// GOOD
const somethingEpic = action$ =>
  action$.ofType('SOMETHING')
    .mergeMap(() =>
      somethingThatMayFail()
        .catch(e => Observable.of({
          type: 'STUFF_BROKE_YO',
          payload: e,
          error: true
        }))
    );

// NOT THE SAME THING!
const somethingEpic = action$ =>
  action$.ofType('SOMETHING')
    .mergeMap(() =>
      somethingThatMayFail()
    )
    .catch(e => Observable.of({
      type: 'STUFF_BROKE_YO',
      payload: e,
      error: true
    }));

有时您确实希望抓住外链,但这通常是最后一回事,仅适用于无法恢复的错误。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用Redux可观察的史诗来测量两次动作之间的持续时间?

如何在单个Redux可观察的史诗中等待/屈服于多个动作?

可观察到的Redux:为多个动作触发相同的史诗

Redux可观察到的史诗链调度重复动作

Redux可观察史诗中的IF

使用Redux Toolkit和Typescript反应可观察的史诗

在Redux可观察到的史诗中的所有动作之后触发一个动作

可观察到的Redux-如何发送动作以启动单独的史诗,然后等待该史诗响应(或超时)

在Redux可观察的史诗中发送请求之前触发动作

如何轻松测试5分钟后发出动作的redux可观察的史诗?

从Redux可观察的史诗中访问状态

Redux可观察史诗与Rxjs问题

如何格式化RxJS redux可观察的史诗来做很多事情?

如何将使用typesafe-actions createAsyncAction创建的动作传递给生成具有正确类型的Redux可观察史诗的函数?

在Redux可观察到的场景中对多个史诗进行编排和排序

Redux基于动作类型及其数据的可观察的取消

测试Redux可观察的史诗的错误处理

redux-observable-在单个史诗中调度多个redux动作

不推荐使用forkJoin来实现多个可观察的功能

如何在史诗中使用“ const”?Redux可观察到的ES6箭头功能

如何使用redux-observable在一部史诗中发出多个动作?

通过多个任务创建一个可观察的对象

第一次调度后可观察到的redux多个动作

如何在可观看Redux的史诗中链接可观察到的RxJS?

Redux-Observable 单个史诗中的多个动作

如何将多个动作与可观察的动作相结合?

Redux中间件和Redux可观察的史诗有什么区别?

如何创建使用类型安全动作AsyncCreator来简化Redux中api请求流的处理的通用异步请求史诗

装饰可观察