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)`
});
我有 '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)`
});