angular - 另一个(Angular)内部的两个或多个顺序请求
问题描述
我正在学习 rxjs,目前正试图弄清楚如何正确地发出一系列请求。例如,它的UserService
一个方法通过用户 id 返回一个用户对象。比方说,在获得对象后,我想利用它包含的信息并发出一些帖子请求,如下所示:
this.userService.getUser(5).subscribe(
user => this.userService.sendEmail(this.makeEmailMessage(user.id, user.name, user.email)).pipe(
delay(1000),
tap(() => console.log('Sending an email'))
).subscribe(
() => this.userService.sendSMS(this.makeSMSMessage(user.id, user.name, user.phone)).subscribe(
() => console.log('Sending sms')
)
)
);
但是它有很多嵌套的订阅,如果涉及到更多的请求,这些订阅可能会变得不可读和难以管理。
可以通过以下方式重写上面的代码:
this.userService.getUser(5).pipe(
switchMap(
user => {
return forkJoin(
this.userService.sendEmail(this.makeEmailMessage(user.id, user.name, user.email)).pipe(
delay(1000),
tap(() => console.log('Sending a email.'))
),
this.userService.sendSMS(this.makeSMSMessage(user.id, user.name, user.phone)).pipe(
tap(() => console.log('Sending an sms'))
)
);
}
)
).subscribe(
res => console.log(res)
);
操作员保持请求的forkJoin
顺序,但短信将首先完成。如果请求顺序无关紧要,那么我认为该代码可以,但是如果要求保持顺序怎么办。
无论如何,我想知道的是,当请求顺序很重要和不重要时,处理此类结构的最佳方法是什么。catchError
另外,说到错误处理,我认为正确的方法是使用管道内的操作员(我使用的地方)来处理它tap
。这是对的吗?
解决方案
如果电子邮件和 SMS 的顺序对您很重要,那么您可以使用switchMap
operator 对 HTTP 调用进行排序
this.userService
.getUser(5)
// If error retrieving user, go straight to error block inside subscribe
// no email, sms, push notification will be sent
.pipe(
switchMap(user => {
return this.userService
.sendEmail(this.makeEmailMessage(user.id, user.name, user.email))
.pipe(
// catchError((err, obs) => of({})) == if you wish to send SMS and Push notification even if sending email failed
delay(1000),
switchMap(() =>
this.userService.sendSMS(
this.makeSMSMessage(user.id, user.name, user.phone)
)
// .pipe(catchError((error, obs) => of({})) if you wish to send Push notification even if sending SMS failed
),
switchMap(() =>
// Push Notification will occur last
this.userService.sendPushNotification(
this.makePushNotificationMessage(
user.id,
user.name,
user.phone
)
)
)
);
})
)
.subscribe({
next: next => {
console.log(next);
},
error: error => {
console.error(error);
}
});
通常,我们在使用运算符时应该非常小心,catchError()
因为天真地使用它会抑制错误消息并使应用程序更难排除故障。catchError
应该在内部将消息记录到控制台或某些记录系统,以便我们知道我们跳过了一个异常。
推荐阅读
- javascript - 使用复选框显示/隐藏多个
我想用一个按钮在一页上显示和隐藏几个表格。不幸的是,我的脚本一次只能显示和隐藏一个表格。
我有一个包含很多查询的页面。表格中还有文本字段。为了更好地概览,带有文本字段的表格应仅在选中复选框时显示。不应在开始时单击该复选框。
- selenium - 如何使用 webdriverjs 模拟“阻止请求 url”
- python - Dict2Columns - PySpark
- python - django rest framework swagger 未映射所有 url
- java - 哪一个是正确的方法,在 void 方法中更改值或返回新对象?
- java - 使用 CSS 在 SWT CCombo 上设置按钮图标
- node.js - Aws LAMBDA:HTTP POST 请求
- go - `type Name *Name` 是如何工作的?
- boolean - Ada 中的布尔大小
- javascript - 用于不同类型标记的多个 for 循环 - 只有第一个循环有效