我目前正在调查RxJS's .merge但是我也会在这里提出这个问题,因为我有时会在这里找到解释。
好吧,我有一个表单,根据用户输入打开一个模态窗口,我订阅模态关闭事件并传回一些数据,我将调用/订阅服务方法后检索一些数据,然后当发生这种情况时,我再次执行相同的操作并调用/订阅另一个服务方法来更新某个日期,然后当它完成时我运行本地方法。所以我在这里有3个嵌套的.subscribe
s
const dialogRef = this.matDialog.open(ModalWindowComponent, {});
let userId = 4; // this is the real world is selected by the user
let userData = {}; // this is actually form data created by the user
// dialog is closed
dialogRef.afterClosed().subscribe((result) => {
if (typeof result === 'string') {
// subscribe to a service to get some data
this.userService.getUser(userId).subscribe((user: any) => {
// do something with the data
let mergedObj = Object.assign({}, user, {newProperty: result});
// subscribe to another service to update the data
this.scbasService.updateUser(userId, mergedObj).subscribe(() => {
this.doSomethingElse(userData);
});
});
}
});
我这里有一个“厄运金字塔”。我记得在使用AngularJS并使用promises时我可以返回下一个服务并链接.then()
。我真的想要压扁我的代码,任何想法?
我怎么能在这里做同样的事情,所以我的代码不会经常缩进?
如果我没有这么好地问过或解释过,请说出来,我会重新解释我的问题。
答案 0 :(得分:3)
你可以这样做:
filter
string
,以便仅处理mergeMap
个结果。getUser
为updateUser
和mergeMap
来电构成内部可观察对象。do
将内部observable合并到外部observable中。subscribe
执行某些操作。subscribe
。否则,什么都不会发生。需要注意的是,在subscribe
次调用中嵌套mergeMap
次调用是一种反模式。
如果需要,可以使用第一个dialogRef
.afterClosed()
.filter(result => typeof result === 'string')
.mergeMap(
result => this.userService.getUser(userId),
(result, user) => Object.assign({}, user, { newProperty: result })
)
.mergeMap(
userWithNewProperty => this.scbasService.updateUser(userId, userWithNewProperty)
)
.do(() => this.doSomethingElse(userData))
.subscribe();
中的结果选择器进一步展平它,以添加属性:
{{1}}