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:
- Modificar la función
test
para que sea asincrónica. - Usar
await
al llamar agetData
.
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 usarawait
dentro de su cuerpo. - Se espera (
await
) el resultado degetData
, asegurando que se reciba el resultado final antes de terminar la ejecución detest
. - 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.