Angular 使用rxjs.subscribe防止末日金字塔,并将.subscribe的数量角平化
我目前正在研究,但我也会在这里问这个问题,因为我发现这里的解释有时很精彩 好的,我有一个表单,根据用户输入打开一个模式窗口,我订阅模式关闭事件,并传回一些数据,在我调用/订阅服务方法检索一些数据后,我将使用这些数据,然后,当发生这种情况时,我再次执行相同的操作,并调用/订阅另一个服务方法来更新某个日期,然后在完成此操作后,我运行一个本地方法。我这里有3个嵌套的Angular 使用rxjs.subscribe防止末日金字塔,并将.subscribe的数量角平化,angular,typescript,rxjs,observable,Angular,Typescript,Rxjs,Observable,我目前正在研究,但我也会在这里问这个问题,因为我发现这里的解释有时很精彩 好的,我有一个表单,根据用户输入打开一个模式窗口,我订阅模式关闭事件,并传回一些数据,在我调用/订阅服务方法检索一些数据后,我将使用这些数据,然后,当发生这种情况时,我再次执行相同的操作,并调用/订阅另一个服务方法来更新某个日期,然后在完成此操作后,我运行一个本地方法。我这里有3个嵌套的.subscribes const dialogRef = this.matDialog.open(ModalWindowComponen
.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和承诺时,我可以返回下一个服务并链接.then()
s。我真的很想把我的代码扁平化,有什么想法吗
我怎么能在这里做同样的事情,这样我的代码就不会不断缩进
如果我没有很好地问自己或解释自己,请说出来,我会重新表述我的问题。你可以这样做:
dialogRef
.afterClosed()
.filter(result => typeof result === 'string')
.mergeMap(result => this.userService
.getUser(userId)
.mergeMap(user => {
let mergedObj = Object.assign({}, user, { newProperty: result });
return this.scbasService.updateUser(userId, mergedObj);
})
)
.do(() => this.doSomethingElse(userData))
.subscribe();
- 使用
,以便只处理过滤器
结果字符串
- 使用
为mergeMap
和getUser
调用组成一个内部可观察对象updateUser
- 再次使用
将内部可见光合并到外部可见光中mergeMap
- 更新用户后,使用
执行操作do
- 然后调用
。否则,什么也不会发生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();
这太棒了-这是一个很好的答案,解释得很好,但是如果我想用非字符串的结果执行一个操作-例如,如果结果不是字符串,我会写入控制台?只需编写另一个可观察对象并订阅它:
dialogRef.afterClosed().filter(result=>typeof result!='string').do(result=>console.log(result)).subscribe()
。根据需要编写尽可能多的筛选器表达式。如果筛选器表达式相互排斥,则只有一个表达式可以执行某些操作。