如何分派和等待可变数量的动作?

How to dispatch and wait for a variable number of actions?

我有一个应用可以显示 table 当前用户所属团队的团队成员统计数据。

应用程序启动时,我:

我在为收到的每个团队 ID 发送团队成员列表操作时没有遇到任何麻烦,但我似乎无法 'wait for' 所有团队成员列表成功操作来发送统计信息操作。

这是我目前正在处理的内容:

// actions
const TEAM_LIST = 'TEAM_LIST';
const TEAM_LIST_SUCCESS = 'TEAM_LIST_SUCCESS';
const TEAM_MEMBER_LIST = 'TEAM_MEMBER_LIST';
const TEAM_MEMBER_LIST_SUCCESS = 'TEAM_MEMBER_LIST_SUCCESS';
const STATS_LIST = 'STATS_LIST';
const STATS_LIST_SUCCESS = 'STATS_SUCCESS';

// action creators
const teamList = () => ({ type: TEAM_LIST });
const teamListSuccess = (teamIds) => ({ type: TEAM_LIST_SUCCESS, teamIds });
const teamMemberList = (teamId) => ({ type: TEAM_MEMBER_LIST, teamId });
const teamMemberListSuccess = (teamId, teamMemberIds) => ({ type: TEAM_MEMBER_LIST_SUCCESS, teamId, teamMemberIds });
const statsList = (teamMemberIds) => ({ type: STATS_LIST, teamMemberIds });
const statsListSuccess = (stats) => ({ type: STATS_LIST_SUCCESS, teamMemberIds, stats });

// epic
const fetchAllStats = (action$) => {
  return action$.ofType(TEAM_LIST_SUCCESS)
    .switchMap((action) => {
      return concat(
        action.teamIds.map(teamMemberList),
        zip(action$.ofType(TEAM_MEMBER_LIST_SUCCESS)
          .take(action.teamIds.length)
        ).map(statsList)
      )
    });
};

我确实使用了错误的 zip/take 组合,因为我对发出的每个 TEAM_MEMBER_LIST_SUCCESS 动作都得到了一个 STATS_LIST 动作。

我如何修改它以使用所有团队成员列表成功操作的结果发送 statsList 操作?

我认为 forkJoin 很适合您的情况。您可以向它传递一组内部可观察对象(一个用于您想要的每个 TEAM_MEMBER_LIST_SUCCESS 操作),它只会在它们全部完成后发出,并且您将获得所有 TEAM_MEMBER_LIST_SUCCESS 操作的数组它捕获。

const fetchAllStats = action$ => action$.pipe(
  ofType(TEAM_LIST_SUCCESS),
  switchMap(action => merge(
    from(action.teamIds.map(teamMemberList)),
    forkJoin(...action.teamIds.map(teamId => action$.pipe(
      filter(action => action.type === TEAM_MEMBER_LIST_SUCCESS && action.teamId === teamId),
      first(),
    ))).pipe(
      mergeMap(actions => actions.map(action => action.teamMemberIds).map(statsList)),
    ),
  )),
)