我有两个模式对话框,选择和确认。这是工作代码:
this.newClientId.pipe(take(1)).subscribe(
response => this.confirmDialogService.ask('DSf').pipe(take(1)).subscribe(
answer => answer ? this.createOrder(response) : this.goBack.next()
)
);
“选择”对话框将值放入newClientId中,然后触发确认对话框,当用户确认创建后便创建了新订单。
有没有嵌套的可能吗?
在这里找到的所有建议都会在设置newClientID之前触发确认对话框。
答案 0 :(得分:1)
我认为可以使用switchMap
运算符来完成,一旦一个发射器就切换到一个新的可观测的物体。
尝试:
this.newClientId.pipe(
take(1),
switchMap(response => {
return [of(response), this.confirmDialogService.ask('DSf')];
}
take(1),
).subscribe(([response, answer])=> answer ? this.createOrder(response) : this.goBack.next());
答案 1 :(得分:0)
合并内部和外部可观察的值:
要合并内部和外部可观察值,可以使用switchMap
rxjs运算符。
this.newClientId
.pipe(
take(1),
switchMap(
clientId => this.confirmDialogService.ask('DSf'),
(clientId, answer) => [clientId, answer]
)
)
.subscribe(([clientId, answer]) => {
console.log(`Received client id is: ${clientId} and confirmation from user is: ${answer}`);
// Perform your logic now
});
switchMap
运算符有多个替代版本,而我已经展示了具有 selector函数的版本(请仔细查看运算符的第二个参数)。通常,如果省略选择器函数,则仅返回内部可观察的值。您可以使用选择器功能自定义输出,以将外部和内部可观测值的值合并到一个数组中,如上例所示。
检查一下我为您在栈闪电战中为用例创建的demo rxjs app。
有关switchMap和switchMap中的选择器功能的更多信息,请参阅此article。如果您是第一次使用switchMap
运算符,我强烈建议您阅读本文。
替代方法:
从您的代码片段中,我了解到您只对可观察对象的第一个值感兴趣。在这种情况下,您可以使用Promises和ES6 async-await
语法,而不是合并可观察变量,以提供一种优雅且简单的解决方案。
使用Promises和async-await,您可以按以下方式更改代码段:
async getResult() {
let clientId = await this.newClientId.toPromise();
let answer = await this.confirmDialogService.ask('DSf'),toPromise();
// perform your logic
}
在上面的代码段中,confirmDialogService.ask()
将不被调用,直到newClientId
返回结果。因此,异步调用现在是同步进行的,并且只有在完成2个异步调用(按指定的顺序)之后,它才会执行方法中的其余代码。
编辑:更新了答案,以使用rxjs运算符解决问题。
答案 2 :(得分:0)
有一种简单的方法可以将两个Observable与rx.zip运算符组合在一起,以避免嵌套订阅
Display()
您能解释一下,为什么在两种情况下都使用“ pipe(take(1))”吗?也许这会改变我的答案。
clientId是Observable还是BehaviourSubject?