如何结合两个可观察对象来创建新的可观察对象?

How to combine two observables to create new observable?

我有两个名为 'PatientsService' 和 'AppointmentService' 的服务。在第三项服务 'AppointedPatientsService' 中,我想订阅 AppointmentService 以获取所有带有 patientId 的预约,之后我想重复订阅 PatientsService.getPatient(patientId) 以获取带有 patientId 的患者数据。然后,我想要 return 名为 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;
}))
);

}

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

你可以使用 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 };
            })
          );

您试图通过同步 return 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);
        });
}