Resumen del Problema: console.log devuelve una promesa pendiente

En el código proporcionado, hay un problema común relacionado con la programación asíncrona en JavaScript. Al llamar a la función test, se devuelve una promesa, lo que provoca que el console.log muestre Promise { <pending> } en lugar de los datos deseados. Esto se debe a que las operaciones de red (como fetchData) son asíncronas, y console.log se ejecuta antes de que la promesa se resuelva.

Solución

Uso de async/await

Una forma conveniente de manejar promesas es utilizando async/await. Aquí se explica cómo reescribir el código para obtener directamente el objeto JSON deseado:

  1. Modificar la función test para que sea asincrónica.
  2. Usar await al llamar a getData.

A continuación, se muestra el código modificado:

'use strict'
import * as moment from "moment";
import { Report } from "./Report";
import { Timeframe } from "./Timeframe";
import { ReportComparison } from "./ReportComparison";

async function test(firstFrom: string, firstTo: string, secondFrom: string, secondTo: string) {
    var pastReport = new Report(new Timeframe(moment(firstFrom), moment(firstTo)));
    var laterReport = new Report(new Timeframe(moment(secondFrom), moment(secondTo)));

    var reportComparison;

    async function getData(pastReport: Report, laterReport: Report) {
        var later = function() {
            return new Promise((resolve, reject) => {
                laterReport.fetchData(data => resolve(data));
            });
        };

        var past = function() {
            return new Promise((resolve, reject) => {
                pastReport.fetchData(data => resolve(data));
            });
        };

        await Promise.all([later(), past()]);

        laterReport.sort();
        reportComparison = new ReportComparison(pastReport, laterReport);

        return {
            pastReport: {
                projects: reportComparison.pastReport.projects,
                timeFrame: reportComparison.pastReport.timeframe,
                totalAutomatedRuns: reportComparison.pastReport.totalAutomatedRuns,
                totalManualRuns: reportComparison.pastReport.totalManualRuns
            },
            laterReport: {
                projects: reportComparison.laterReport.projects,
                timeFrame: reportComparison.laterReport.timeframe,
                totalAutomatedRuns: reportComparison.laterReport.totalAutomatedRuns,
                totalManualRuns: reportComparison.laterReport.totalManualRuns
            },
            trends: reportComparison.trends
        };
    }

    return await getData(pastReport, laterReport);
}

test("20170707", "20170707", "20170710", "20170710").then(res => console.log(res));

Explicación de Cambios

  • La función test ahora es async, lo que permite usar await dentro de su cuerpo.
  • Se espera (await) el resultado de getData, asegurando que se reciba el resultado final antes de terminar la ejecución de test.
  • Finalmente, el resultado se puede imprimir con console.log en el contexto de la promesa resuelta, eliminando así el estado pendiente.

Con estos cambios, se obtendrá el objeto JSON esperado en lugar de una promesa pendiente. Esta es la manera adecuada de manejar las operaciones asíncronas en JavaScript.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *