Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

138
Vistas
Manejo de datos asíncronos en la clase JS

Objetivo: quiero crear una clase que aborde una interfaz de noticias y represente los datos en la vista. Mi clase ( MyNews ) tiene varios métodos y un método es fetchNews() . En este método obtengo los datos de la API. Los datos de la API deben asignarse en una variable de clase ( news ). En otro método ( showNews() ) quiero acceder a los datos para iterar sobre ellos.

Mi problema: soy principiante en js y me pregunto cómo consultar los datos. Según tengo entendido, el flujo es así: el constructor llama a fetchNews fetch news primero recibe una promesa y espera hasta que se resuelva la promesa, luego los datos se asignan al miembro pero el JS asíncrono se está ejecutando js no espera en este punto hasta la promesa se resuelve y continúa trabajando con la matriz vacía. Este es exactamente mi problema.

Pregunta ¿Qué debo hacer o cambiar para obtener los datos correctamente? Para que pueda construir una lista HTML, por ejemplo.

Mi código JS

 class MyNews { news = []; apiUrl = "https://jsonplaceholder.typicode.com/posts"; constructor() { this.news; this.fetchNews(); } fetchNews() { fetch(this.apiUrl) .then(async (data) => { this.news = await data.json(); console.log("A:",this.news.length); // i have results }) .catch((err) => { console.log(err) }); // ... } showNews() { console.log("B:",this.news.length); // empty array return this.news; } } n = new MyNews; console.log("C:", n.showNews().length );

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Sugeriría agregar una función getAndShowNews() a su clase.

Luego nos aseguraremos de devolver la promesa de la llamada de búsqueda fetchNews() , para que podamos await en otra función asíncrona.

En la función getAndShowNews() () esperaremos el resultado de fetchNews() (una promesa), esto asegurará que se llenen las noticias. Luego mostraremos las noticias recorriendo cada elemento.

Podría hacer esto en una función fuera de la clase, pero parece tener sentido hacerlo en la clase.

 class MyNews { news = []; apiUrl = "https://jsonplaceholder.typicode.com/posts"; constructor() { this.fetchNews(); } fetchNews() { return fetch(this.apiUrl) .then(async (data) => { this.news = await data.json(); }) .catch((err) => { console.log(err) }); // ... } showNews(newsElementId, count = 8) { let newsElement = document.getElementById(newsElementId); for(let newsItem of this.news.slice(0,count)) { let el = document.createElement('li'); el.innerText = newsItem.title; newsElement.appendChild(el); } } async getAndShowNews(newsElementId) { // Wait for the fetchNews() call to complete... await this.fetchNews(); // Show the news... this.showNews(newsElementId); } } n = new MyNews(); n.getAndShowNews('news');
 <b>News</b> <ol id='news'> </ol>

about 4 years ago · Juan Pablo Isaza Denunciar

0

El problema es que fetch() es una función asíncrona. Esto es lo que realmente sucede:

  1. El constructor se llama
  2. se inicia fetchNews
  3. Constructor probablemente termina antes de fetchNews
  4. showNews probablemente se ejecuta antes de que termine fetchNews

Lo primero que viene a la mente es usar la palabra clave await o usar promesas directamente. Sin embargo, esto no resuelve completamente su problema, porque el constructor no puede ser una función asíncrona.

Recomiendo esta solución:

Mueva la llamada de fetchNews a un método init en la clase MyNews y hágalo asíncrono.

 class MyNews { ... async fetchNews() { await fetch(...); } ... async init() { await fetchNews(); } ... } const news = new MyNews(); await news.init(); news.showNews();

Puede encontrar más información sobre los constructores asíncronos en este hilo de stackoverflow .

por cierto: el this.news; en el constructor parece innecesario.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Un par de problemas:

  1. La primera es que fetchNews es un proceso asíncrono. En su ejemplo, showNews siempre será 0 porque fetchNews no ha obtenido nada cuando se llama showNews . Podemos mitigar algo de esto moviendo la llamada de esos métodos fuera de la clase.

  2. Tiene una combinación extraña de fetch y async/await : es mejor quedarse con uno u otro.

 class MyNews { apiUrl = 'https://jsonplaceholder.typicode.com/posts'; // `async/await` function - fetches the JSON, and // sets the `news` field to the parsed JSON async fetchNews() { try { const response = await fetch(this.apiUrl); if (response.ok) this.news = await response.json(); } catch (err) { this.error = err.message; } } formatNews() { return this.news.map(n => { return `<p>${n.title}</p>`; }).join(''); } // Return the news or the error if there was one. showNews() { if (!Array.isArray(this.news)) return this.error; return this.formatNews(); } } // Piecing it together we create a new // object, call and `await` `fetchNews` and // then call `showNews` async function main() { const myNews = new MyNews(); await myNews.fetchNews(); document.body.innerHTML = myNews.showNews(); } main();
 p { border: 1px solid #787878; padding: 0.3em; border-radius: 5px; margin: 0.2em; text-transform: capitalize; } p:hover { cursor: pointer; background-color: #ffffd0; }

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda