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.

Problemas con funciones anidadas y cadenas de promesas con manejo de errores – ¿cómo puedo lograr que esto funcione?

He aprendido el uso encadenado de promesas con manejo de errores como se muestra en la primera sección de código. Sin embargo, no he podido lograr que el siguiente principio funcione con mi código en la nube Parse. Mi código en la nube funciona correctamente, pero tengo funciones gigantes que necesito refactorizar y organizar.

Mi objetivo aquí

Es tener funciones en la nube más pequeñas que pueda llamar sin repetir código, por lo que quiero tener una función para desencadenar un error si un usuario ya es parte de un grupo Parse.Role, de lo contrario, agregaré el usuario al Role. Por supuesto, si se desencadena un error, quiero detener el resto de la ejecución.

Por favor, vea los siguientes fragmentos de código. Agradecería algunas opiniones profesionales.

function addOne(number) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(number += 1);
    }, 1000);
  });
}

/// Lanza un error a menos que el número sea 5
var test = addOne(5);

test.then(function(currentValue) {
  currentValue ++;
    if (currentValue > 7) {
      return Promise.reject(Error("Valor inicial demasiado alto"));
    } else {
      return Promise.resolve(currentValue);
    }
})

.then(function(value) {
  value -= 2;
    if (value < 5) {
      return Promise.reject(Error("Valor inicial demasiado bajo"));
    } else {
      return Promise.resolve(value);
    }
})

.then(function(finalValue) {
  finalValue ++;
    if (finalValue != 6) {
      return Promise.reject(Error("No es el punto ideal"));
    } else {
      console.log("¡Elegiste bien!" + String(Promise.resolve("PRUEBA")));
    }
});
/// ESTA ES UNA VERSIÓN QUE NO FUNCIONA ADECUADAMENTE

/// Comprobar si el usuario forma parte del grupo
Parse.Cloud.define("mmDoesUserHaveGroup", async function(request) {
  let userID = request.params.user;
  // Buscar clase de usuario por ID de usuario
  let userQuery = await new Parse.Query(Parse.User).equalTo('objectId', userID).find({useMasterKey: true});
  let userObject = userQuery[0];
  // Comprueba si el usuario está en todos los roles
  const query = await new Parse.Query(Parse.Role).equalTo('users', userObject).find({ useMasterKey: true })
  .then(function() {
    if (query.length != 0) {
      return Promise.reject(Error('El usuario ya forma parte del grupo'));
    } else {
      return Promise.resolve();
    }
  });
});

Parse.Cloud.define("ccCreateGroup", async function(request) {
  let userID = request.user.id;
  const doesUserHaveGroup = Parse.Cloud.run("mmDoesUserHaveGroup", {user: userID});
    doesUserHaveGroup
    .then(function() {
      return Promise.resolve("Crear grupo acción siguiente");
    })
    .catch(error => Error(error.message));
});

/// OTRA VERSIÓN QUE TAMPOCO FUNCIONA

/// Devuelve falso si el usuario no forma parte del grupo o no es el propietario del grupo, de lo contrario, error
Parse.Cloud.define("mmDoesUserHaveGroup", async function(request) {
  let userID = request.params.user;
  // Buscar clase de usuario por ID de usuario
  let userQuery = await new Parse.Query(Parse.User).equalTo('objectId', userID).find({useMasterKey: true});
  let userObject = userQuery[0];
  // Comprueba si el usuario está en todos los roles
  const query = await new Parse.Query(Parse.Role).equalTo('users', userObject).find({ useMasterKey: true })
  .then(function() {
    if (query.length != 0) {
      return true;
    } else {
      return false;
    }
  });
});

Parse.Cloud.define("ccCreateGroup", async function(request) {
  let userID = request.user.id;
  const doesUserHaveGroup = Parse.Cloud.run("mmDoesUserHaveGroup", {user: userID});
    doesUserHaveGroup
    .then(function(groupStatus) {
      if (groupStatus) {
        return Promise.reject(Error("El usuario ya tiene un grupo"));
      } else {
        return Promise.resolve("Crear grupo acción siguiente");
      }
    });
});
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Explicación del problema:

    En ambas versiones de los fragmentos de código proporcionados, el problema radica en el uso de await y then() juntos. La palabra clave await se utiliza para pausar la ejecución de la función hasta que se resuelva o sea rechazada una promesa. Por otro lado, .then() se utiliza para encadenar promesas, donde la función dentro de then() se ejecuta una vez que se resuelve la promesa. La idea detrás de async/await es hacer que el código asíncrono parezca y se comporte como el código síncrono, pero en estos fragmentos de código, await no se está utilizando correctamente.

    En el primer fragmento de código, query recibe el valor de otra promesa dentro de otro .then(). Esto hace que query sea una promesa anidada en lugar del resultado real. Además, el error se está lanzando en un .then() en lugar de en un .catch(), lo que puede hacer que se ignore el error.

    En el segundo fragmento de código, el bloque if dentro del .then() de la función mmDoesUserHaveGroup no está devolviendo nada, lo que hace que la promesa se resuelva con undefined incluso si el usuario es parte del grupo.

    Fragmentos de código revisados con el uso correcto de async/await:

    // Versión revisada de la función mmDoesUserHaveGroup
    Parse.Cloud.define("mmDoesUserHaveGroup", async function(request) {
      let userID = request.params.user;
    
      try {
        let userQuery = await new Parse.Query(Parse.User).equalTo('objectId', userID).find({useMasterKey: true});
        let userObject = userQuery[0];
    
        let query = await new Parse.Query(Parse.Role).equalTo('users', userObject).find({ useMasterKey: true });
    
        if (query.length != 0) {
          return Promise.reject(Error('El usuario ya es parte del grupo'));
        } else {
          return Promise.resolve();
        }
      } catch (error) {
        return Promise.reject(Error(error.message));
      }
    }); 
    
    // Versión revisada de la función ccCreateGroup
    Parse.Cloud.define("ccCreateGroup", async function(request) {
      let userID = request.user.id;
      try {
        await Parse.Cloud.run("mmDoesUserHaveGroup", {user: userID});
        return Promise.resolve("Siguiente paso: crear grupo");
      } catch (error) {
        return Promise.reject(Error(error.message));
      }
    });
    
    

    En la versión revisada de mmDoesUserHaveGroup, se han utilizado bloques try-catch para simplificar el manejo de errores. Primero intenta obtener el usuario y comprobar si es parte de algún rol. Si hay un error, la función rechaza la promesa con el mensaje de error.

    En ccCreateGroup, se utilizan bloques try-catch para manejar las promesas. La función mmDoesUserHaveGroup se llama utilizando await, que pausa la ejecución de la función hasta que la promesa se resuelva o se rechace. Si el usuario no tiene un rol, la función se resuelve con el mensaje “Siguiente paso: crear grupo”. De lo contrario, la función se rechaza con el mensaje de error.

Comments are closed.