es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Esperando múltiples llamadas RxJS antes de ejecutar el siguiente bloque de código.

Tengo una lista de calles y las iteraré. Dentro del bucle for, llamaré a un endpoint para cada una de estas calles. El endpoint me devuelve información sobre la calle solicitada. Quiero almacenar cada respuesta en un array de objetos y después de que todas las solicitudes hayan terminado, quiero ejecutar el siguiente bloque de código.

Aquí está mi problema:
Hago todas las llamadas, almaceno todos mis datos en el array de objetos, pero si uso en el siguiente bloque de código mi array de objetos prellenado, la longitud es igual a 0… Aquí está mi código:

export class MyComponent{
  addressInfoArray: AddressInfo[] = [];

  // algún código ...

  prepareStreetInformations(): void {
    // algún código ....

    this.fillArray(streets, url);
    this.doSomethingWithArray(this.addressInfoArray); // <--- la longitud es 0 y no espera a que termine el método fillArray()
  }
}

fillArray(streets: Street[], url: string): void { // streets tiene una longitud de 150
  for (const street of streets) {
    this.http.get<addressinfo>(`${url}/street.name`).subscribe(response => {
      this.addressInfoArray.push(response);
    });
  }
}

Entonces mi pregunta es: ¿Cómo puedo hacer que el método doSomethingWithArray() espere a que el método fillArray() haya terminado por completo y por qué el método doSomethingWithArray() no ve que mi array de objetos ya está lleno?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para que el método doSomethingWithArray() espere la finalización del método fillArray(), se pueden utilizar promesas u observables. Con observables, se puede utilizar el operador forkJoin() para esperar a que todas las solicitudes HTTP finalicen antes de ejecutar el siguiente bloque de código. Así es cómo se puede modificar el código utilizando observables:

    export class MyComponent{
      addressInfoArray: AddressInfo[] = [];
    
      // some code ...
    
      prepareStreetInformations(): void {
        // some code ....
    
        this.fillArray(streets, url).subscribe(responses => {
          this.addressInfoArray = responses;
          this.doSomethingWithArray(this.addressInfoArray);
        });
      }
    
      fillArray(streets: Street[], url: string): Observable<addressinfo[]> {
        const requests = streets.map(street => this.http.get<addressinfo>(`${url}/${street.name}`));
        return forkJoin(requests);
      }
    }
    

    En el método fillArray(), utilizamos la función map() para crear un array de observables que representan las solicitudes HTTP. Luego, utilizamos la función forkJoin() para esperar a que todos los observables se completen y emitan sus valores como un array de respuestas. Devolvemos este array como un observable desde el método fillArray(), que se puede suscribir en el método prepareStreetInformations(). En este método, asignamos las respuestas a la propiedad addressInfoArray y luego llamamos al método doSomethingWithArray().

    La razón por la que el método doSomethingWithArray() ve la longitud de addressInfoArray como 0 es porque las solicitudes HTTP son asíncronas, lo que significa que se están ejecutando en segundo plano mientras el hilo principal continúa ejecutando el resto del código. Por lo tanto, cuando llamas al método doSomethingWithArray() inmediatamente después de llamar al método fillArray(), es posible que las solicitudes HTTP aún no se hayan completado y que el addressInfoArray no esté completamente poblado. Al utilizar observables para esperar la finalización de las solicitudes HTTP, te aseguras de que addressInfoArray esté completamente poblado antes de pasarlo al método doSomethingWithArray().</addressinfo[]>

Comments are closed.