RxJS:获取多个响应

RxJS: Get multiple response

我有 'nested' 个请求、团队创建和团队头像上传,其中第二个依赖于第一个并且只有当头像不为 null 时才应发送(我已经使用过滤器运算符完成了此操作)。我现在需要的是在订阅方法中访问这两个响应。

this.team.createTeam(teamRequest)
    .pipe(
        filter(() => avatar),
        flatMap(next => this.team.uploadLogo(avatar, next.body.uuid)
    ).subscribe(responses => {
        // so, I want response from both createTeam and uploadLogo in responses
});

您可以将 map 运算符通过管道传输到内部请求并发送两个响应。尝试以下

this.team.createTeam(teamRequest)
  .pipe(
    filter(() => avatar),
    flatMap(next => 
      this.team.uploadLogo(avatar, next.body.uuid).pipe(
        map(res => ({ avatar: res, team: next }))
      )
    )
  ).subscribe(responses => {
      // responses.avatar: response from `this.team.uploadLogo(avatar, next.body.uuid)` 
      // responses.team: response from `this.team.createTeam(teamRequest)` 
  });

我已经 return 编辑了一个对象以供说明。您可以根据您的要求以任何形式 return 它。例如。作为数组 map(res => [ next, res ])).

更新:iif 函数代替 filter 运算符

如果在 filter 条件失败时你仍然想订阅 source observable,我能想到的最快的方法是放弃 filter 运算符并使用 iif 函数反而。尝试以下

const upload = (avatar, team): Observable<any> => {
  return this.team.uploadLogo(avatar, next.body.uuid).pipe(
    map(res => ({ avatar: avatar, team: team }))
  );
};

iif(() =>
  !!avatar,
  this.team.createTeam(teamRequest).pipe(flatMap(next => upload(avatar, next.body.uuid))),
  this.team.createTeam(teamRequest)
).subscribe(
  responses => {
    // if `avatar` is null
    // responses: response from `this.team.createTeam(teamRequest)`
    // or
    // if `avatar` is non-null
    // responses.avatar: response from `this.team.uploadLogo(avatar, next.body.uuid)` 
    // responses.team: response from `this.team.createTeam(teamRequest)` 
  }
);

更新:检查 flatMap

中的 avatar

正如@bryan60 所建议的,这里有一个既不使用 filter 也不使用 iif 的更简洁的代码。而是检查 flatMap 和 returns of(next) 中的 avatar 是否为空。

this.team.createTeam(teamRequest).pipe(
  flatMap(next => {
    if (!!avatar) {
      return this.team.uploadLogo(avatar, next.body.uuid).pipe(
        map(res => ({ avatar: res, team: next }))
      );
    }
    return of(next);
  })
).subscribe(responses => {
    // if `avatar` is null
    // responses: response from `this.team.createTeam(teamRequest)`
    // or
    // if `avatar` is non-null
    // responses.avatar: response from `this.team.uploadLogo(avatar, next.body.uuid)` 
    // responses.team: response from `this.team.createTeam(teamRequest)` 
});