He estado luchando con la naturaleza asíncrona de javascript en este proyecto desde hace un tiempo.
Hay muchas preguntas similares sobre este tema, pero siento que todas son ligeramente diferentes y me han dificultado obtener una solución funcional.
He estado tratando de crear una API con estos métodos.
Empecé a escribir todos mis métodos con devoluciones de llamadas, lo cual estaba bien aunque era simple. Pero ahora me está causando problemas. Así que escribí algunos envoltorios con util.promisify que funcionó muy bien.
Tengo este método de auditoría que funciona perfectamente.
const audit = (req, res, next) => { Domains.audit(req.params.url) .then((data) => { res.json(data); }) .catch((err) => { res.json(err); }) };Devuelve este objeto que se planea asignar a "mensajes"
{ "warnings": [ "This url 301 redirects to https://www.google.com. Please update your entry." ], "errors": [] }Aquí está el problema.
Estoy luchando para implementar el método auditAll. Intenté usar devoluciones de llamada y promesas, pero siempre regresa antes de que mis llamadas de auditoría modifiquen el "informe" que devuelvo
Aquí hay un pseudocódigo de lo que sigo sin poder crear
auditAll(callback) { // Get all domains with getAll() and make them look like this report = { '123' : { 'url' : 'https://google.com', 'other_props' : '...' } '124' : { 'url' : 'https://google2.com', 'other_props' : '...' } }; // For each report item // run an audit which returns a message object // assign that to it's spot in the report report[item_key][messages] = audit(item.url) // Report returns to the browser before the audits finish with every solution I've implemented. // They send to my console like 50ms later. callback(report) }Su función de auditoría () necesitaría devolver la Promesa que está creando ...
const audit = (req, res, next) => { return Domains.audit(req.params.url) .then((data) => { res.json(data); }) .catch((err) => { res.json(err); }) };... y luego su método auditAll() debe esperar a que finalicen todas las llamadas audit(). Dado que parece que está llamando a audit() una vez para cada elemento en su matriz de informes, podría verse así, usando Array.map() y Promise.all():
Promise.all( Object.values(report).map( item => audit(item.url).then( message => item[messages] = message ) ) ).then(() => callback(report));Anexo: en realidad, hay cierta falta de claridad en su pregunta: auditAll llama "audit (url)", pero ha proporcionado el código para "audit (req, res, next)", por lo que no estoy seguro de cómo son. relacionado. La idea aquí es que audit() debería devolver la promesa de un mensaje
audit(url) { return someAsyncFunc(url).then(() => message); }que luego se puede utilizar como he descrito.