Javascript rxjs相当于使用';返回';;
我想实现下面类似的东西(如果使用承诺,它们很容易实现) 如果我使用可观察的东西而不是承诺,我不知道如何做到这一点,但这是我迄今为止尝试过的方法Javascript rxjs相当于使用';返回';;,javascript,typescript,rxjs,Javascript,Typescript,Rxjs,我想实现下面类似的东西(如果使用承诺,它们很容易实现) 如果我使用可观察的东西而不是承诺,我不知道如何做到这一点,但这是我迄今为止尝试过的方法 doSomething(sID){ let student; let teacher; service.getStudent(sID).pipe( switchMap(studentR=>{ student = studentR; return service.getTeacher(stude
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();
}
正如您所看到的,我的rxjs版本与promise版本相比似乎太长了,我觉得我做得不对。
async/await
主要是作为可读性功能开发的,因此在视觉上非常简洁自然。
使用旧式的Promise
语法,您将获得更长的函数。
因此,简而言之,您可以很好地使用observables,而且由于预期的语法差异,它的使用时间更长。以下是如何将当前代码转换为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))
)
))
}
在您的案例中,您可以避免保存教师和学生的值,因为我认为在管道上传播它们在您的用例中是非常正确的 为此,在请求教师后,我将映射响应,并将数据作为元组返回学生和教师 如果老师不活跃,抛出一个错误可能是一个优雅的解决方案,如果你想对错误做些什么,如果你不想做,你也可以返回空的,这是一个不发出并简单完成的可观察结果 因此,这是我的解决方案,考虑到请求“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...*/ }
);
}
希望这有帮助 但是如果我需要做一些事情,比如如果teacherSomethingResponse为null,那么做另一个调用呢?这意味着我的链是错误的,因为我不应该输入到达服务的行。teacherSomething只要teacher.Active==false
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...*/ }
);
}