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.

Vuelve solo después de que cada elemento haya terminado sus llamadas de método.

He estado luchando con la naturaleza asíncrona de JavaScript en este proyecto durante un tiempo.

Hay muchas preguntas similares sobre este tema, pero siento que todas son ligeramente diferentes y me han dificultado encontrar una solución funcional.

He estado intentando crear una API con estos métodos.

  • getAll: una lectura de archivo asíncrona
  • audit
  • auditAll

Al principio, escribí todos mis métodos con callbacks, lo cual estaba bien cuando era simple. Pero ahora me está causando problemas, así que he escrito algunos envoltorios con util.promisify, lo cual ha funcionado 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 está planeado para ser asignado a “messages”

{
    "warnings": [
        "Esta URL redirecciona a https://www.google.com con un redireccionamiento 301. Por favor, actualiza tu entrada."
    ],
    "errors": []
}

Aquí está el problema.

Estoy luchando para implementar el método auditAll.
He intentado utilizar callbacks y promesas, pero siempre devuelve 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) {
    // Obtener todos los dominios con getAll() y hacer que se vean así
    informe = {
        '123' : {
            'url' : 'https://google.com',
            'otras<em>propiedades': '...'
        },
        '124' : {
            'url' : 'https://google2.com',
            'otras</em>propiedades': '...'
        }
    };

    // Para cada elemento del informe
    // ejecutar una auditoría que devuelve un objeto de mensaje
    // asignar eso a su lugar en el informe
    informe[clave_del_elemento]['mensajes'] = audit(item.url)

    // El informe se envía al navegador antes de que las auditorías terminen con todas las soluciones que he implementado.
    // Se envían a mi consola unos 50 ms más tarde.
    callback(informe);
}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que estás luchando con la naturaleza asíncrona de JavaScript y cómo manejarla correctamente al realizar múltiples llamadas a la API. Una solución a este problema es usar promesas y async/await.

    Puedes modificar tu método auditAll para usar Promise.all y ejecutar todas las llamadas de auditoría en paralelo, esperando a que todas ellas terminen antes de devolver el informe final. Aquí tienes un ejemplo:

    async function auditAll(req, res, next) {
        try {
            const domains = await getAll(); // reemplaza esto con tu método para obtener todos los dominios
            const reporte = {};
    
            await Promise.all(domains.map(async (dominio) => {
                const mensajes = await audit(dominio.url);
                reporte[dominio.id] = { url: dominio.url, mensajes };
            }));
    
            res.json(reporte);
        } catch (err) {
            next(err);
        }
    }
    

    En este ejemplo, se asume que el método getAll devuelve un array de objetos de dominio que tienen las propiedades ‘id’ y ‘url’. Se asume que el método audit devuelve un objeto de mensaje como el que mostraste anteriormente.

    El método auditAll ahora se declara como asíncrono para que podamos usar await para esperar a que el método getAll termine antes de continuar. Luego utilizamos Promise.all para llamar al método audit para cada dominio en paralelo y esperar a que todas ellas terminen. Una vez que todas las llamadas de auditoría terminan, construimos el objeto de informe final con los mensajes y lo enviamos de vuelta como una respuesta. Si se producen errores, los enviamos al siguiente middleware.

    Usar async/await y Promise.all puede simplificar tu código y hacer que sea más fácil manejar llamadas asíncronas en JavaScript.

Comments are closed.