Consulte el código siguiente como referencia.
export const listenToHotels = (hotelIds: string[]): Observable < Hotel[] > => { return new Observable < Hotel[] > ((observer) => { const hotels: any = []; hotelIds.forEach((hotelId) => { let roomingList: any; return FirestoreCollectionReference.Hotels() .doc(hotelId) .onSnapshot( (doc) => { roomingList = { hotelId: doc.id, ...doc.data() } as Hotel; console.log(`roomingList`, roomingList); hotels.push({ ...roomingList }); }, (error) => observer.error(error) ); }); //Check for error handling observer.next(hotels); console.log('hotels', hotels); }); };Como puede ver, estoy tratando de ejecutar un forEach en un hotelId Array y en ese firestore se está ejecutando el oyente. Ahora quiero guardar la respuesta y enviarla a la matriz de hoteles, pero me da un error de objeto de error no extensible. La cuestión es que el observador y la consola. log ('hoteles', hoteles) se ejecutan primero debido a que la promesa se ejecuta en una etapa posterior.
Por favor, hágame saber cómo puedo resolver este problema.
Creo que podrías usar map en lugar de forEach, porque podrías usar await con map
ejemplo de uso de mapa y espera: https://flaviocopes.com/javascript-async-await-array-map/
Echa un vistazo a forkJoin . Toma una matriz de Observables y se suscribe a ellos al mismo tiempo.
Este ejemplo está escrito en Angular, pero los operadores deben ser idénticos siempre que use una versión actual de rxjs .
map )forkJoin luego se agrega como un contenedor a la matrizforkJoin . Todos los objetos harán la llamada.subscribe()Entonces en tu caso:
calls . Cada elemento es la lógica observable que publicasteforkJoin(calls).subscribe() para hacer todas las llamadasexport const listenToHotels = (hotelIds: string[]): Observable<Hotel[]> => { const hotelsObservable = hotelIds.map((hotelId) => { let roomingList: any; return new Observable<Hotel>((observerInside) => { FirestoreCollectionReference.Hotels() .doc(hotelId) .onSnapshot( (doc) => { roomingList = { hotelId: doc.id, ...doc.data() } as Hotel; observerInside.next(roomingList); }, (error) => observerInside.error(error) ); }); }); const combinedObservable = combineLatest(hotelsObservable); return combinedObservable; //Check for error handling };El problema era cómo estaba manejando los observables encadenados (la ejecución de la promesa se retrasa que un código normal porque se colocarán primero en la microcola). Deben manejarse con zip o combineLatest, pero este último es mucho mejor en este caso de uso, ya que necesitamos los valores más recientes para los observables.