Estás viendo una versión antigua de esta página. Ve a la versión actual.

Comparar con el actual Ver el historial de la página

« Anterior Versión 3 Siguiente »


Si en nuestras aplicaciones tenemos peticiones que tardan mucho tiempo, varios segundos, pueden surgir problemas: peticiones que acaben en timeout, bloqueo de recursos en el backend, etc. Para solucionar esto y optimizar estas consultas, debemos hacerlas de forma asíncrona. Para ello, tendremos que hacer la petición desde nuestro frontend, recibir un id del backend, e ir haciendo pooling desde el front hasta que estén listos los datos. Los pasos serían los siguientes:

  1. FRONT hace petición a BACK.
  2. BACK guarda en base de datos un registro que contendrá un id de petición y los datos que se piden cuando estén listos.
  3. BACK inicia el procesamiento necesario de forma asíncrona. Este procesamiento acabará con los datos solicitados en el registro de base de datos que hemos creado.
  4. BACK responde a FRONT con el id que hemos guardado.
  5. FRONT se queda haciendo peticiones constantes (cada x tiempo) con el id a BACK.
  6. BACK comprueba si ya están los datos en el registro de base de datos, devolviéndolos si es así, y enviando un 202 en caso contrario.

Veamos como implementaríamos esto en ambas partes.

Frontend

Después de la primera petición, con la que obtendremos el id de solicitud, para hacer pooling podemos hacerlo de la siguiente manera:

obtenerResolucion(numSolicitud) {
  // Llamada al método REST para obtener los datos
  ServicioRest.obtenerResolucion(numSolicitud, this.token)
    .then((response) => {
      if(response.status === 202){
        // Si no están listos los datos esperamos para volver a hacer la petición, en este caso 5000ms, 5s, le ponemos tiempo de espera que queramos
        setTimeout(()=>{this.obtenerResolucion(numSolicitud)}, 5000);
      } else {
        // Procesamiento de los datos ya obtenidos
        ...
      }
    })
    // Si se produce un error lo indicamos con un toast
    .catch(() => {
      this.$store.dispatch("global/setShowSpinner", false); // Quitamos el spinner de carga - Hay que adaptarlo a cómo lo hagamos en nuestra aplicacion
      this.$toast.add({
        severity: "error",
        summary: "Error",
        detail: "Se ha producido un error en el proceso.",
        life: 3000,
      });
    });
},

Backend

Para ejecutar código de forma asíncrona en Spring Boot, podemos utilizar CompletableFuture.runAsync( ... ), y con esto el método que inicia la solicitud tendría esta estructura:

public ResponseEntity<String> solicitudDatos( ... ) {
	// Inicia proceso y obtiene id
    String id = iniciaProceso() //Función que cree el registro en base de datos y devuelva el id
	CompletableFuture.runAsync( () -> {
		// Código asíncrono, que termine poniendo el resultado en base de datos
	});
    // Devolvemos el id de la peticion
	return new ResponseEntity<>(id, HttpStatus.OK );
}

Y para el método al que el front estará haciendo pooling solo necesitaremos una consulta normal a base de datos, con un JpaRepository, y comprobar si el campo de los datos está vacío o no, dando la respuesta correspondiente.

  • Sin etiquetas