Angular 有条件地执行switchMap,否则,取消所有操作而不触发错误事件
我正在用Angular 10做一个web应用程序。我试着用可观察的而不是承诺来工作,但有时很难建立一个执行流程 我想完成这个流程:Angular 有条件地执行switchMap,否则,取消所有操作而不触发错误事件,angular,typescript,rxjs,Angular,Typescript,Rxjs,我正在用Angular 10做一个web应用程序。我试着用可观察的而不是承诺来工作,但有时很难建立一个执行流程 我想完成这个流程: 呈现确认模式 如果确认有一个值({isConfirmed:true}),则表示加载(条件如下) 执行switchMap以开始执行HTTP调用 如果任何HTTP调用失败,则隐藏加载并显示警告消息 逻辑: send(title: string, message): Observable<any> { const isConfirmed: Prom
{isConfirmed:true}
),则表示加载(条件如下)switchMap
以开始执行HTTP调用 send(title: string, message): Observable<any> {
const isConfirmed: Promise<{isConfirmed: boolean}> = this.alertService.warningConfirmation(
'Send message',
'Are you sure you want to send the message?',
'Send',
'Cancel'
);
return from(isConfirmed)
.pipe(
tap(res => res.isConfirmed ? this.loadingService.present() : EMPTY),
switchMap(res => from(this.service.httpCallOneGetUsers())
.pipe(
map(users => users.map(user => user.email)),
switchMap(emails => this.service.httpCallTwoSendMessage(title, message, emails))
)
),
finalize(() => this.loadingService.dismiss()),
tap({
next: () => console.log('Message sent!'),
error: () => console.log('Could not send the message.')
})
);
}
send(标题:字符串,消息):可观察{
const isconfirm:Promise=this.alertService.warningConfirmation(
“发送消息”,
'您确定要发送此消息吗?',
“发送”,
“取消”
);
从返回(已确认)
.烟斗(
点击(res=>res.isconfirm?this.loadingService.present():EMPTY),
switchMap(res=>from(this.service.httpCallOneGetUsers())
.烟斗(
map(users=>users.map(user=>user.email)),
switchMap(emails=>this.service.httpCallTwoSendMessage(标题、消息、电子邮件))
)
),
完成(()=>this.loadingService.disclose()),
水龙头({
下一步:()=>console.log('messagesent!'),
错误:()=>console.log('无法发送消息')
})
);
}
当我取消确认时,将触发错误事件。此外,荷载从未显示
我在第一个switchMap
中有两个HTTP调用,两个调用都可能失败,一个返回承诺,另一个返回可观察的。这就是为什么我在from()
中添加了第一个HTTP调用
我的目标是:
isConfirmed:true
,则有条件地执行/输入开关映射。否则,取消所有并退出逻辑,而不触发错误事件
点击
或完成
以隐藏加载并向用户显示成功/错误消息的最佳位置我想你可以这样做:
return from(isConfirmed)
.pipe(
switchMap(res => res.isConfirmed ? of(res) : EMPTY),
tap(() => this.loadingService.present()),
switchMap(res => from(this.service.httpCallOneGetUsers()).pipe(...)
...
唯一的变化是,我在开始时使用了switchMap
和tap()
。如果res.isconfirm===false
则重新输入EMPTY
,这将不会触发以下任何运算符(它只是一个完成的
通知)。当它为true
时,我将返回原始res
对象,其中包含of(res)
要隐藏加载,最好的操作符很可能是
finalize()
,因为它是在链被释放时触发的,即在链完成、出错或取消订阅之后。我认为您可以按以下方式执行:
return from(isConfirmed)
.pipe(
switchMap(res => res.isConfirmed ? of(res) : EMPTY),
tap(() => this.loadingService.present()),
switchMap(res => from(this.service.httpCallOneGetUsers()).pipe(...)
...
唯一的变化是,我在开始时使用了switchMap
和tap()
。如果res.isconfirm===false
则重新输入EMPTY
,这将不会触发以下任何运算符(它只是一个完成的
通知)。当它为true
时,我将返回原始res
对象,其中包含of(res)
要隐藏加载,最好的操作符很可能是finalize()
,因为它是在链完成、出错或取消订阅后被释放时触发的。1
如果确认结果为isConfirmed:true
,则有条件地执行/输入开关映射
试试看。例如:
来自(已确认)。管道(
过滤器((res)=>!!res.isconfirm)
...
)
这将仅发出与过滤条件匹配的值
2.
哪里是添加分接或最终确定的最佳位置
finalize
:最后,如果任何订阅在此之前失败,则执行该订阅
点击
:无论您想在哪里执行某些操作。例如,如果您想向用户打印电子邮件,则需要将tap
指令放在管道中包含该数据的部分
总结:
来自(已确认)。管道(
过滤器((res)=>!!res.isconfirm),
switchMap((res)=>from(this.service.httpCallOneGetUsers()),
map((用户)=>users.map((用户)=>user.email)),
开关映射((电子邮件)=>
this.service.httpCallTwoSendMessage(标题、消息、电子邮件)
),
完成(()=>this.loadingService.disclose()),
水龙头({
下一步:()=>console.log(“消息已发送!”),
错误:()=>console.log(“无法发送消息”),
})
);
注意:最后一个点击
就像订阅结果的接收者,这就是为什么它是最后一个。但是该代码应该放在订阅中
更新(来自评论)
若要在不满足条件时最终确定可观测值,应执行以下操作:
来自(已确认)。管道(
开关图((分辨率)=>{
如果(决议已确认){
this.loadingService.present();
从(this.service.httpCallOneGetUsers())返回;
}否则{
投掷者(“”);
}
}),
map((用户)=>users.map((用户)=>user.email)),
开关映射((电子邮件)=>
this.service.httpCallTwoSendMessage(标题、消息、电子邮件)
),
完成(()=>this.loadingService.disclose()),
水龙头({
下一步:()=>console.log(“消息已发送!”),
错误:()=>console.log(“无法发送消息”),
})
);
如果条件为true,管道将按预期顺序执行。如果条件为false,则从第一个开关映射
跳到完成
1
如果确认结果为isConfirmed:true
,则有条件地执行/输入开关映射
试试看。例如:
来自(已确认)。管道(
过滤器((res)=>!!res.isconfirm)
...
)
这将仅发出与过滤条件匹配的值
2.
哪里是添加抽头或定稿的最佳位置