我想在下面实现类似的功能(如果使用诺言,这很容易)
async doSomething(sID){
let student = await service.getStudent(sID);
let teacher = await service.getTeacher(student.TeacherID);
if(!teacher.Active){
return;
}
await service.teacherSomething(teacher);
await service.studentSomething(student);
}
如果我使用可观察变量而不是promise,我不知道如何执行此操作,但这是我到目前为止尝试过的
doSomething(sID){
let student;
let teacher;
service.getStudent(sID).pipe(
switchMap(studentR=>{
student = studentR;
return service.getTeacher(student.TeacherID);
}),
switchMap(teacherR=>{
teacher = teacherR;
if(!teacher.Active){
return of(null);
}else{
return service.teacherSomething(teacher);
}
}),
swicthMap(teacherSomethingResponse=>{
if(teacherSomethingResponse==null){
return of(null);
}else{
return service.studentSomething(student);
}
})
}).subscribe();
}
如您所见,与promise版本相比,我的rxjs版本似乎太长了,我觉得我做的方式不正确。
答案 0 :(得分:3)
这是将当前代码转换为Rx样式的方法。如果不满足条件,takeWhile将完成您的可观察性
function doSomething(sID) {
return from(service.getStudent(sID)).pipe(
switchMap(student =>
service.getTeacher(student.TeacherID).pipe(
takeWhile(teacher => teacher.Active),
switchMap(teacher => service.teacherSomething(teacher).pipe(takeWhile(res => res))),
switchMap(() => service.studentSomething(student))
)
))
}
答案 1 :(得分:1)
async/await
主要是为了提高可读性而开发的,因此视觉上很简洁是很自然的。
使用旧式Promise
语法,您将获得更长的功能。
因此,简而言之-您可以很好地使用observables,并且由于预期的语法差异,它的使用时间更长。
答案 2 :(得分:0)
在您的情况下,您可以避免保存教师和学生的价值,因为我认为在用例中将其传播到管道中是正确的。
为此,在请求老师之后,我将映射,并将学生和老师的数据作为元组返回。
如果老师没有上课,抛出错误可能是一个很好的解决方案,如果您想对错误做一些事情,或者您还返回空,那是可观察到的,不会发出,只是完成。
所以,这是我的解决方案,考虑到请求'teacherSomething'和'studentSomething'可以并行完成,因为它们似乎并不相互依赖
doSomething(sID){
service.getStudent(sID).pipe(
switchMap(studentR =>
service.getTeacher(student.TeacherID).pipe(map((teacherR) => [studentR, teacherR]))),
switchMap(([studentR, teacherR]) => {
if(!teacherR.Active){
throw new Error('Teacher is not active'); // or return EMPTY
}
// I think this two request may have been done in parallel, if so, this is correct.
return zip(service.teacherSomething(teacher), service.studentSomething(student));
})
).subscribe(
([teacherSomethingR, studentSomethingR]) => {/* do something with responses */},
(error) => { /* Do something if teacher not active, or some request has been error...*/ }
);
}
如果请求无法并行完成,我将做与之前(switchMap)相同的操作,并返回响应的元组,以便在需要时执行某些操作。如果不需要,您可以避免最后一步:
doSomething(sID){
service.getStudent(sID).pipe(
switchMap(studentR =>
service.getTeacher(student.TeacherID).pipe(map((teacherR) => [studentR, teacherR]))),
switchMap(([studentR, teacherR]) => {
if(!teacherR.Active){
throw new Error('Teacher is not active'); // or return EMPTY
}
// Both request teacher something and student something done in 'serie'
return service.teacherSomething(teacher)
.pipe(switchMap((teacherSomethingR) =>
service.studentSomething(student)
.pipe(map((studentSomethingR) => [teacherSomethingR, studentSomethingR]))
))
})
).subscribe(
([teacherSomethingR, studentSomethingR]) => {/* do something with responses */},
(error) => { /* Do something if teacher not active, or some request has been error...*/ }
);
}
希望这会有所帮助!