Cuando invocas una función asíncrona, ésta no se resuelve hasta que ha completado su trabajo (por ejemplo, la petición al servidor que estás solicitando).
Eso significa que el código que va tras el fetch
, el return enumContent
, se ejecuta ANTES que las funciones definidas dentro de los then()
.
Tienes varias formas de resolver el problema. La más sencilla es proporcionando una función de retrollamada como parámetro, pero la más elegante es haciendo uso de funciones asíncronas.
Te pongo un ejemplo de cada una de ellas y una descripción superficial de cada solución.
Función de retrollamada
Una retrollamada es un método de comunicación entre procesos por el cual proporcionamos como parámetro una función que puede ser llamada una o varias veces cuando se produzca un evento (por ejemplo, al finalizar un trabajo).
const SRC_REFS_DATA_CONTENTS =
"https://api.github.com/users/ojgarciab/events/public";
const setEnumContent = (retrollamada) => {
let enumContent = [];
let chapterNumber = 0;
fetch(SRC_REFS_DATA_CONTENTS)
.then(response => response.json())
.then(data => {
data.forEach(element => {
if (element.type == "PushEvent") {
enumContent.push({
reference: element.repo.name,
chapter: ++chapterNumber,
});
}
});
/* Aquí hacemos la retrollamada con los datos */
retrollamada(enumContent);
});
}
/* Ahora llamamos a la función proporcionando qué hacer en la retrollamada */
setEnumContent(datos => console.log(datos));
Función asíncrona
Una función asíncrona es una función que puede ejecutar en su interior otras funciones asíncronas como si se ejecutaran de manera secuencial (usando await
), ejecutándose cada tarea después de que la anterior haya finalizado.
const SRC_REFS_DATA_CONTENTS =
"https://api.github.com/users/ojgarciab/events/public";
/* Definimos la función como asíncrona */
const setEnumContent = async () => {
let enumContent = [];
let chapterNumber = 0;
/* Obtenemos la respuesta y los datos */
const respuesta = await fetch(SRC_REFS_DATA_CONTENTS);
const data = await respuesta.json();
/* Procesamos los datos obtenidos */
data.forEach(element => {
if (element.type == "PushEvent") {
enumContent.push({
reference: element.repo.name,
chapter: ++chapterNumber,
});
}
});
/* Devolvemos los valores */
return enumContent;
}
/* Ahora llamamos a la función tratándola como una promesa */
setEnumContent().then(datos => console.log(datos));