我正在尝试在 rxjs 中发送请求,如果用户上传了文件,这是有条件的。在此之后,如果文件在那里,我将其附加到我发送的用户对象,然后我需要在发布到文件端点后修补用户。
我遇到的问题是,因为它在第一个请求中处于 if 条件,我知道我无法订阅它。我可以通过做我试图避免if { } else { }
来绕过它。
这是它的样子。
if (fileSelected) {
this.dataService.type('files').post(fileSelected).subscribe((response) => {
this.user.file = response;
// I need to then post the updated user to the patch endpoint.
});
}
this.dataService.type('users').patch(this.user).subscribe(() => {
});
显然,在上面的示例中(我目前的做法(,它不会等待第一个请求完成。我知道我可能会使用.pipe
并将一些东西管道到最后,但正如我之前所说,由于这是第一个请求,我不完全确定这将如何完成。
您希望启动值为 fileSelected
的可观察流,然后有条件地切换到其他流。
const user$ = of(fileSelected).pipe(
switchMap(selected => selected
? this.dataService.type('files').post(fileSelected)
: of(undefined)
),
switchMap(response => {
this.user.file = response; // will be undefined if not selected
return this.dataService.type('users').patch(this.user);
})
);
user$.subscribe(value => console.log(value));
您还可以使其与用户对象更相关,这样您就不会从函数式编程内部引用 this.user
属性。这更接近于使其成为可以重用的 RxJS 运算符。
function sendFiles(user, fileSelected): Observable<any> {
return of(user).pipe(
switchMap(user => {
const send$ = fileSelected ? this.dataService.type('files').post(fileSelected) : of(undefined);
return send$.pipe(map(response => (user.file = response, user)));
),
switchMap(user => this.dataService.type('users').patch(user))
);
}
sendFiles(this.user, fileSelected).subscribe(value => console.log(value));
或者更简单:
function sendFiles(user: User, fileSelected: boolean, {type}: DataService): Observable<any> {
const send$ = fileSelected ? type('files').post(fileSelected) : of(undefined);
return send$.pipe(
map(file => ({...user, file})),
switchMap(user => type('users').patch(user))
);
}
为此使用 mergeMap
this.dataService.type('files').post(fileSelected).pipe(
mergeMap(response => {
this.user.file = response;
return this.dataService.type('users').patch(this.user)
})
).subscribe(x => console.log("all done"));