嗨,我正在尝试使用 angular 9 中的 rxjs,并且我正在尝试根据 observable 的响应有条件地进行调用,但如果没有嵌套订阅,似乎无法让它工作。我已经阅读了几篇文章,包括这个和这个,但我似乎无法解决我的问题。
在我的阅读中,我还阅读了这篇 SO post
单击确认按钮时触发 中的confirmed()方法DialogConfirmService
请注意,我尝试了两次以上的重构,但发布的重构是我一直在尝试的示例。
我当前的工作解决方案(我想摆脱嵌套订阅)
this.dialogConfirmService
.confirmed()
.pipe(take(1))
.pipe(map(x => {
this.isSaving = true;
return x;
})
)
.subscribe(confirmed => {
if (confirmed) {
this.myService.save('', '')
.pipe(take(1))
.subscribe(
(data) => this.onSuccess(data),
(error) => this.handleError(error)
);
}
});
Run Code Online (Sandbox Code Playgroud)
我的重构失败 1
this.dialogConfirmService
.confirmed()
.pipe(take(1))
.pipe(
map(x => {
this.isSaving = true;
console.log(x);
return x;
}
),
mergeMap(cv =>
this.myService.save(
this.rulesetForm.controls.name.value,
JSON.parse(this.rulesetForm.controls.definiation.value)
)
)).subscribe(j => this.isSaving = false);
Run Code Online (Sandbox Code Playgroud)
我的重构失败 2
onSave(): void {
this.dialogConfirmService
.confirmed()
.pipe(take(1))
.pipe(
flatMap(confirmed => this.onConfirm(confirmed)),
);
}
private onConfirm(confirmed: any) {
if (confirmed) {
this.isSaving = true;
this._ruleSetMapperService.save(
this.rulesetForm.controls.name.value,
JSON.parse(this.rulesetForm.controls.definiation.value)
);
} else {
return Observable.create(function(observer) {
observer.next(confirmed);
observer.complete();
});
}
}
Run Code Online (Sandbox Code Playgroud)
下面是调用的其他代码(为了完整起见)
对话服务
..other stuff...
export class DialogConfirmService {
...other stuff...
public confirmed(): Observable<any> {
return this.dialogRef
.afterClosed()
.pipe(take(1),
map(res => {
return res;
})
);
}
}
Run Code Online (Sandbox Code Playgroud)
我的储蓄服务
export class MyService {
save(rsn: string, rsd: string): Observable<any> {
...other stuff... (generates the body)
return this._http.post('myUrl', JSON.stringify(body), { headers: this.headers });
}
}
Run Code Online (Sandbox Code Playgroud)
以下是一些可以避免嵌套订阅的替代方法:
1)
this.dialogConfirmService
.confirmed()
.pipe(
tap(() => (this.isSaving = true)),
switchMap((confirmed) =>
confirmed ? this.myService.save('', '') : of(null)
),
catchError((error) => throwError(error))
)
.subscribe((data) => this.onSuccess(data));
Run Code Online (Sandbox Code Playgroud)
RxJS 运算符:
tap - 用于副作用;
switchMap- 完成前一个 observable 并根据条件订阅新的 observable(switch和map操作符的组合)。请记住,即使条件为假,您也始终需要涵盖这两种情况。
catchError, throwError- 好吧,用于处理错误
2.
this.dialogConfirmService
.confirmed()
.pipe(
filter((confirmed) => !!confirmed),
tap(() => (this.isSaving = true)),
switchMap(() => this.myService.save('', '')),
catchError((error) => throwError(error))
)
.subscribe((data) => this.onSuccess(data));
Run Code Online (Sandbox Code Playgroud)
filter - 在这种情况下,只有当条件为真时,它才会订阅下一个 observable。
3.
this.dialogConfirmService
.confirmed()
.pipe(
switchMap((confirmed) =>
iif(() => confirmed, this.myService.save('', ''))
),
catchError((error) => throwError(error))
)
.subscribe((data) => this.onSuccess(data));
Run Code Online (Sandbox Code Playgroud)
iif- 这类似于三元运算符。它接受一个条件函数和两个 observable,但是不需要第二个 observable。
关于您进行的 http 调用,您不应该对有效负载进行字符串化。
| 归档时间: |
|
| 查看次数: |
172 次 |
| 最近记录: |