Tengo dos funciones (una función dentro del controlador y una función en un servicio). Quiero llamar a la función de servicio desde la función del controlador. Después de llamar a la función de servicio, esta función llama a una función de base de datos (usando Sequelize).
Controlador:
exports.getMilestoneById = async (req, res, next) => { const milestoneId = req.params.milestoneId; try{ milestoneService.getMilestoneById(milestoneId) .then(mielstone => { console.log("Milestone in tehn: " + mielstone) }); console.log("Milestone: " + milestone); res.status(200).json({message: 'Milestone fetched', milestone: milestone}); } catch (error){ if (!error.statusCode){ error.statusCode = 500; } } }Servicio:
exports.getMilestoneById = async (milestoneId) => { Milestone.findByPk(milestoneId) .then(milestone => { console.log("In Service: " + milestone) return milestone.get(); }) .catch(err => { console.log("Error" + err); });}
El problema: no recupero un hito.
Ok, intentemos poner un poco de orden aquí.
Tu código no espera la respuesta de Promise .
milestoneService.getMilestoneById(milestoneId) // <- this returns a promise // all stuff below here doesn't wait for the promise to complete and can't see its result console.log("Milestone: " + milestone); res.status(200).json({message: 'Milestone fetched', milestone: milestone});En su lugar, escribir algo como:
milestoneService.getMilestoneById(milestoneId) .then(mielstone => { console.log("Milestone in tehn: " + mielstone); // I moved all the stuff that needs to wait in here!! console.log("Milestone: " + milestone); res.status(200).json({message: 'Milestone fetched', milestone: milestone}); });Esto funcionaría como se esperaba.
Agregaste ese async antes de las funciones, ¡me imagino que podrías darle un buen uso! async / await lo ayuda a limpiar el flujo de promesas al permitir que la función de ajuste espere sus resultados, por lo que escribe algo como:
const milestone = await milestoneService.getMilestoneById(milestoneId) console.log("Milestone: " + milestone); res.status(200).json({message: 'Milestone fetched', milestone: milestone});También funcionaría como se esperaba.
... ¡O no! Te perdiste casi todos los retornos en tu código. Como regla general, intente hacer que cada función siempre devuelva algo, ¡especialmente si son promesas! Asi como:
exports.getMilestoneById = async (milestoneId) => { const milestone = await Milestone.findByPk(milestoneId); return milestone.get(); /* I don't suggest handling the error here, because it doesn't bubble well! /* If there's an error what would this function return? }Después
exports.getMilestoneById = async (req, res, next) => { const milestoneId = req.params.milestoneId; try { const milestone = await milestoneService.getMilestoneById(milestoneId) console.log("Milestone: " + milestone); // just return this return res.status(200).json({ message: 'Milestone fetched', milestone }); } catch (error){ if (!error.statusCode){ error.statusCode = 500; } // call next with the error! return next(error); } }Cuando devuelva el resultado en esta devolución de llamada:
.then(milestone => { console.log("In Service: " + milestone) return milestone.get(); }) De hecho, está configurando el valor de retorno para la función de devolución de llamada, no el valor de retorno para el milestone service.getMilestoneById() . Debido a que su función es una función async , debe usar la sintaxis de espera asíncrona de Javascript, que solo obtendrá el valor una vez que se resuelva la promesa.
exports.getMilestoneById = async (milestoneId) => { const milestone = await Milestone.findByPk(milestoneId) .catch(err => { console.log("Error" + err); }); console.log("In Service: " + milestone) return milestone }Esto debería ser lo mismo para la función de su controlador:
exports.getMilestoneById = async (req, res, next) => { const milestoneId = req.params.milestoneId; try{ const milestone = await milestoneService.getMilestoneById(milestoneId) console.log("Milestone: " + milestone); res.status(200).json({message: 'Milestone fetched', milestone: milestone}); } catch (error){ if (!error.statusCode){ error.statusCode = 500; } } }