【问题标题】:How to combine two observables to create new observable?如何结合两个可观察对象来创建新的可观察对象?
【发布时间】:2020-03-04 08:57:17
【问题描述】:

我有两个名为“PatientsService”和“AppointmentService”的服务。在第三个服务“AppointedPatientsService”中,我想订阅 AppointmentService 以获取所有带有 PatientId 的预约,之后我想重复订阅 PatientService.getPatient(patientId) 以获取带有 PatientId 的患者数据。然后,我想返回一个名为 allAppointedPatients 的新数组,它包含所有与患者数据的约会。我试过这个...

 getAppointments() {
let allAppointments: Appointment[] = [];
const allAppointedPatients: AppointedPatient[] = [];

return this.appointmentService.fetchAllAppointments().pipe(
  take(1),
  tap(appointments => {
  allAppointments = appointments;

  for (const appointment of allAppointments) {
    this.patientsService.getPatient(appointment.patientId).pipe(
      tap(patient => {
        const newAppointment = new AppointedPatient(patient.firstName,
                                                  patient.lastName,
                                                  patient.address,
                                                  patient.casePaperNumber,

 appointment.appointmentDateTime);
        allAppointedPatients.push(newAppointment);
      })
    ).subscribe();
  }
  return allAppointedPatients;
}),
pipe(tap((data) => {
  return this.allAppointedPatients;
}))
);

}

这不起作用,我知道必须有更好的方法来处理这种情况。请帮忙...

【问题讨论】:

  • 你在哪里初始化你的数组?
  • 寻找 rxjs 的 switchMap 操作符
  • @Ramesh - 在返回语句之前初始化数组.. 查看更新的代码快照
  • @enno.void - 我尝试使用开关映射。但我很困惑我应该在哪个可观察对象上使用 switchMap

标签: javascript angular ionic-framework rxjs ionic4


【解决方案1】:

通过尝试同步返回 allAppointedPatients 数组,您将异步代码(可观察对象)与同步代码弄乱了。

首先了解异步代码在 Javascript 中是如何工作的,以及为什么 Observables(流)如此有用。

试试下面的代码,确保你理解了。当然,我无法对其进行测试,因此如果需要,请自行更改。

getAppointments(): Observable<AppointedPatient[]> {
    return this.appointmentService.fetchAllAppointments()
        .pipe(
            switchMap(appointments => {

                const pacientAppointments = [];

                for (const appointment of allAppointments) {

                    // Extract the data aggregation outside or create custom operator
                    const pacientApp$ = this.patientsService.getPatient(appointment.patientId)
                        .pipe(
                            switchMap((pacient) => of(
                                new AppointedPatient(
                                    patient.firstName,
                                    patient.lastName,
                                    patient.address,
                                    patient.casePaperNumber,
                                    appointment.appointmentDateTime
                                )
                            ))
                        )

                    pacientAppoinments.push(pacientApp$);
                }

                return forkJoin(pacientAppointments);
        });
}

【讨论】:

  • 感谢您的帮助!它工作得很好,虽然我仍然理解代码
  • 如何定义这个 getAppointments() 函数的返回类型?因为当我订阅它时,我无法将它分配给指定的患者..
  • 我用返回类型编辑过,但你实在不确定的时候也可以用“any”。
  • 以上代码不适用于 AngularFire(实时数据库)。我只使用 AngularFire 更新了患者和预约服务(以前是使用 HttpClient)
  • @PrashantGujar 因为forkJoin 正在等待 Observable 完成。在“实时数据库”中,可观察对象可能没有完成,但会继续推送数据。请改用merge 运算符。
【解决方案2】:

你可以使用 forkJoin:

forkJoin(
            getSingleValueObservable(),
            getDelayedValueObservable()
            // getMultiValueObservable(), forkJoin on works for observables that complete
          ).pipe(
            map(([first, second]) => {
              // forkJoin returns an array of values, here we map those values to an object
              return { first, second };
            })
          );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多