redux-observable 调度操作

redux-observable dispatch actions

我需要使用 redux-observable 以某种顺序分派一些动作,但是,分派只需要最后一个动作。请看例子:

export const fetchClientsEpic = (action$, { dispatch }) =>
  action$
    .ofType(fetchClients)
    .mapTo(fetchClientsPending(true))
    .mergeMap(() => {
      return ajax
        .getJSON('some/get/clients/api')
        .map((clients: IClient[]) => {
          return fetchClientsSuccess(
            map(clients, (client, index) => ({
              key: index,
              ...client,
            })),
          );
        });
    });

fetchClientsSuccess 是与客户一起发送的,但 fetchClientsPending 不是,我完全不明白为什么。我可以使用 dispatch 因为我在参数中得到它,但我觉得这不是好的解决方案(?)。我想应该在流中完成。我从 RxJs 和 redux-observable 开始。有可能吗?

运算符是 Observable 链,其中一个流的输入是另一个流的输出。因此,当您使用 mapTo 时,您是在将一个操作映射到另一个操作。但是然后你的 mergeMap 映射那个 Pending 动作并将它映射到另一个内部 Observable 执行 ajax 等等,有效地抛弃了 Pending 动作。所以把 RxJS 想象成一系列数据流经的管道(a stream)

虽然没有灵丹妙药,但在这种特殊情况下,您可以通过在内部 Observable

的末尾使用 startWith 来实现您想要实现的目标
export const fetchClientsEpic = (action$, { dispatch }) =>
  action$
    .ofType(fetchClients)
    .mergeMap(() => {
      return ajax
        .getJSON('some/get/clients/api')
        .map((clients: IClient[]) => {
          return fetchClientsSuccess(
            map(clients, (client, index) => ({
              key: index,
              ...client,
            })),
          );
        })
        .startWith(fetchClientsPending(true)); // <------- like so
    });

这实际上与使用 concatof(action) first 相同,只是 shorthand.

export const fetchClientsEpic = (action$, { dispatch }) =>
  action$
    .ofType(fetchClients)
    .mergeMap(() => {
      return Observable.concat(
        Observable.of(fetchClientsPending(true)),
        ajax
          .getJSON('some/get/clients/api')
          .map((clients: IClient[]) => {
            return fetchClientsSuccess(
              map(clients, (client, index) => ({
                key: index,
                ...client,
              })),
            );
          })
      );
    });

也就是说,我建议不要同步分派另一个操作来设置抓取挂起的状态,而是依赖原始 fetchClients 操作本身来达到相同的效果。您的减速器应该假设,如果看到这样的操作,无论如何仍然会以某种方式开始获取。这为您节省了样板文件并在 micro-perf 上有所帮助,因为您不需要 运行 通过 reducer、epics 和重新渲染两次。

虽然没有规则,所以如果您对此有强烈的感觉,那就去吧:)