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.

Reutilización de un objeto Promise existente si existe.

Tengo un objeto de diálogo que mostrará, bueno, diálogos. Hay muchos puntos de entrada para mostrar diálogos, por ejemplo, yesNo(), message(), confirm(), etc. Sin embargo, todos estos métodos básicamente llaman al mismo otro método, llamado showSimpleDialog(título, mensaje, botones).

Me gustaría que todos estos métodos (incluido showSimpleDialog) devolvieran una promesa, pero hay un problema:

yesNo() {
  return new Promise((resolve, reject) => {
    axios
      .get(......)
      .then(this.showSimpleDialog(...));
  }
}

Como puedes ver, en el ejemplo anterior, se me impide tanto devolver la promesa que showSimpleDialog haría como pasar la promesa instanciada a showSimpleDialog.

La primera opción es imposible porque ya estamos en una promesa diferente en el momento en que tenemos acceso a ella. La segunda opción no es posible porque el objeto Promise aún no está disponible dentro del constructor. Bueno, técnicamente, en este caso en particular sí lo está (exactamente porque ya estamos en una promesa diferente), pero algunas de mis funciones de entrada son síncronas y otras asíncronas, y simplemente no puedo usar el mismo patrón de código para lograr el mismo efecto en ambos casos.

Investigué al respecto y encontré esto, pero el autor sugiere que este enfoque es defectuoso y arcaico desde el principio.

Entonces, ¿cuál sería el enfoque correcto para devolver una promesa funcional desde TODOS los puntos de entrada, mientras que los puntos de entrada aún pueden reutilizar las promesas entre sí?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para devolver una Promesa funcional desde todos los puntos de entrada mientras se puede reutilizar las Promesas entre sí, se puede utilizar el método resolve del constructor de Promesas.

    Aquí hay una implementación de ejemplo:

    class Dialogo {
      constructor() {
        this.promesa = null;
      }
    
      mostrarDialogoSimple(titulo, mensaje, botones) {
        return new Promise((resolve, reject) => {
          // Implementación de tu diálogo aquí
          // Llama a resolve con el resultado que deseas devolver
          resolve(resultado);
        });
      }
    
      mostrarDialogo(titulo, mensaje, botones) {
        // Verifica si ya hay una promesa en progreso
        if (this.promesa) {
          return this.promesa;
        }
    
        // Crea una nueva promesa y almacena una referencia a ella
        this.promesa = new Promise((resolve, reject) => {
          this.mostrarDialogoSimple(titulo, mensaje, botones)
            .then(resultado => {
              // Reinicia la promesa almacenada
              this.promesa = null;
              // Resuelve la promesa con el resultado
              resolve(resultado);
            })
            .catch(error => {
              // Reinicia la promesa almacenada
              this.promesa = null;
              // Rechaza la promesa con el error
              reject(error);
            });
        });
    
        return this.promesa;
      }
    
      siNo() {
        return this.mostrarDialogo("¿Sí o No?", "Por favor selecciona sí o no", ["Sí", "No"]);
      }
    
      mensaje() {
        return this.mostrarDialogo("Mensaje", "Esto es un mensaje", ["Aceptar"]);
      }
    
      confirmar() {
        return this.mostrarDialogo("Confirmar", "¿Estás seguro?", ["Sí", "No"]);
      }
    }
    

    Con esta implementación, todos los puntos de entrada (siNo(), mensaje(), confirmar()) llaman al método mostrarDialogo, que maneja la creación y almacenamiento de una nueva Promesa. Si ya hay una Promesa en progreso, simplemente devuelve la Promesa almacenada.

    El método mostrarDialogoSimple devuelve una nueva Promesa que se resuelve con el resultado deseado. Cuando la Promesa se resuelve, mostrarDialogo reinicia la Promesa almacenada y resuelve la Promesa devuelta por mostrarDialogo con el resultado. Si ocurre un error, mostrarDialogo rechaza la Promesa devuelta por mostrarDialogo con el error.

    Este enfoque te permite reutilizar Promesas en todos los puntos de entrada al mismo tiempo que devuelve una Promesa funcional para cada punto de entrada.

Comments are closed.