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");
}
});
});
davy.ai
Explicación del problema:
En ambas versiones de los fragmentos de código proporcionados, el problema radica en el uso de
await
ythen()
juntos. La palabra claveawait
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 dethen()
se ejecuta una vez que se resuelve la promesa. La idea detrás deasync/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 quequery
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ónmmDoesUserHaveGroup
no está devolviendo nada, lo que hace que la promesa se resuelva conundefined
incluso si el usuario es parte del grupo.Fragmentos de código revisados con el uso correcto de async/await:
En la versión revisada de
mmDoesUserHaveGroup
, se han utilizado bloquestry-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 bloquestry-catch
para manejar las promesas. La funciónmmDoesUserHaveGroup
se llama utilizandoawait
, 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.