在 rxjs 中嵌套订阅
Nexted subscribes in rxjs
我有这个功能,可以从每个请求中获取信息并将其传递给下一个请求。实现这个的最佳方法是什么。这行得通,但鉴于我有嵌套订阅,我担心从长远来看这可能会出现一些问题。
onSubmit(){
this.loadingController.create({keyboardClose:true, message:'Submitting Info...'})
.then(loadingEl => {
loadingEl.present()
this.sharedService.uploadImage(this.state['image']).subscribe(imgUrl => {
this.sharedService.addVisitor(this.state['first_name'],
this.state['last_name'],
this.state['role'],
this.location,
imgUrl,
this.state['visitee_email'],
this.state['visitee_phone'],
this.state['visitee_name'],
this.state['company'])
.subscribe(visitor => {
console.log(visitor)
this.sharedService.addQuestionnaire(visitor.id)
.subscribe(questionnaire => {
console.log(questionnaire)
//dismiss the loading element
loadingEl.dismiss();
// navigate away
this.router.navigate(['/home'])
})
})
}, error => {
loadingEl.dismiss()
console.log(error)
this.alertController.create({header: "An error ocurred...",
message: "Could not submit visitor info.",
buttons: [{text: 'Okay', handler: () => this.router.navigateByUrl('/home')}]}).then(alertEl => {
alertEl.present()
})
})
})
}
}
- 我上传图片,从云存储中获取url
- 再次请求添加访客并获取访客 ID
- 然后我将现有的输入问卷上传到另一个api
如果有人可以缩小或帮助我改进这段代码,将不胜感激!
你可以这样改:
import { switchMap, catchError, throwError } from 'rxjs/operators';
this.sharedService
.uploadImage(this.state['image'])
.pipe(
switchMap(imgUrl => this.sharedService
.addVisitor(
this.state['first_name'],
this.state['last_name'],
this.state['role'],
this.location,
imgUrl,
this.state['visitee_email'],
this.state['visitee_phone'],
this.state['visitee_name'],
this.state['company']
)
),
switchMap(({ id }) => this.sharedService.addQuestionnaire(id)),
catchError((error: any) => throwError(error))
)
.subscribe(
questionnaire => {
console.log(questionnaire)
loadingEl.dismiss();
this.router.navigate(['/home'])
},
error => {
loadingEl.dismiss()
console.log(error)
this.alertController.create({
header: "An error ocurred...",
message: "Could not submit visitor info.",
buttons: [{text: 'Okay',
handler: () => this.router.navigateByUrl('/home')}]}).then(alertEl => alertEl.present())
}
);
我有这个功能,可以从每个请求中获取信息并将其传递给下一个请求。实现这个的最佳方法是什么。这行得通,但鉴于我有嵌套订阅,我担心从长远来看这可能会出现一些问题。
onSubmit(){
this.loadingController.create({keyboardClose:true, message:'Submitting Info...'})
.then(loadingEl => {
loadingEl.present()
this.sharedService.uploadImage(this.state['image']).subscribe(imgUrl => {
this.sharedService.addVisitor(this.state['first_name'],
this.state['last_name'],
this.state['role'],
this.location,
imgUrl,
this.state['visitee_email'],
this.state['visitee_phone'],
this.state['visitee_name'],
this.state['company'])
.subscribe(visitor => {
console.log(visitor)
this.sharedService.addQuestionnaire(visitor.id)
.subscribe(questionnaire => {
console.log(questionnaire)
//dismiss the loading element
loadingEl.dismiss();
// navigate away
this.router.navigate(['/home'])
})
})
}, error => {
loadingEl.dismiss()
console.log(error)
this.alertController.create({header: "An error ocurred...",
message: "Could not submit visitor info.",
buttons: [{text: 'Okay', handler: () => this.router.navigateByUrl('/home')}]}).then(alertEl => {
alertEl.present()
})
})
})
}
}
- 我上传图片,从云存储中获取url
- 再次请求添加访客并获取访客 ID
- 然后我将现有的输入问卷上传到另一个api
如果有人可以缩小或帮助我改进这段代码,将不胜感激!
你可以这样改:
import { switchMap, catchError, throwError } from 'rxjs/operators';
this.sharedService
.uploadImage(this.state['image'])
.pipe(
switchMap(imgUrl => this.sharedService
.addVisitor(
this.state['first_name'],
this.state['last_name'],
this.state['role'],
this.location,
imgUrl,
this.state['visitee_email'],
this.state['visitee_phone'],
this.state['visitee_name'],
this.state['company']
)
),
switchMap(({ id }) => this.sharedService.addQuestionnaire(id)),
catchError((error: any) => throwError(error))
)
.subscribe(
questionnaire => {
console.log(questionnaire)
loadingEl.dismiss();
this.router.navigate(['/home'])
},
error => {
loadingEl.dismiss()
console.log(error)
this.alertController.create({
header: "An error ocurred...",
message: "Could not submit visitor info.",
buttons: [{text: 'Okay',
handler: () => this.router.navigateByUrl('/home')}]}).then(alertEl => alertEl.present())
}
);