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

239
Vistas
setTimeout recursivo con async/await

Estoy ejecutando un setTimeout, de forma recursiva, por lo que solo quiero llamar a la API una vez por minuto.

Aquí está mi código:

 ;(async function ticker (minutes) { try { const res = await coingecko.global() const { market_cap_percentage } = res.data.data dominance = { btc: market_cap_percentage.btc, eth: market_cap_percentage.eth } console.log({ dominance }) } catch (ex) { console.log(ex.message) } finally { setTimeout(ticker, minutes * 60 * 1000) } })(1)

El problema es:

  • Cuando inicio mi servidor, llama a la API inmediatamente
  • Se tarda un minuto en realizar una segunda llamada (comportamiento esperado)
  • Después de la segunda llamada, comienza a llamar a la API secuencialmente, sin tiempo de espera.
over 4 years ago · Santiago Trujillo
6 Respuestas
Responde la pregunta

0

Lo llama inmediatamente porque eso es lo que hace su código. Ejecuta la llamada a la función ticker(1) inmediatamente.

Cuando llama a ticker desde setTimeout(ticker, ...) , no está pasando el parámetro de minutes a esa función; es por eso que setTimeout() no se retrasa correctamente.

Si no desea que se ejecute de inmediato, deshágase del IIFE y simplemente inícielo con setTimeout() . Y, luego, cuando llame a ticker() desde la devolución de llamada setTimeout() , asegúrese de pasarle los argumentos de los minutes , ya sea pasando el tercer argumento a setTimeout() o haciendo una pequeña función de devolución de llamada para él.

Aquí hay una implementación:

 async function ticker(minutes) { try { const res = await coingecko.global() const { market_cap_percentage } = res.data.data dominance = { btc: market_cap_percentage.btc, eth: market_cap_percentage.eth } console.log({ dominance }) } catch (ex) { console.log(ex.message) } finally { setTimeout(ticker, minutes * 60 * 1000, minutes); } } setTimeout(ticker, minutes * 60 * 1000, 1);
over 4 years ago · Santiago Trujillo Denunciar

0

¿Quizás solo necesitas usar algún administrador de horarios, como bree ?

A partir de su código

  1. no necesitas IIFE aquí. Simplemente llame a setTimeout(() => ticker(1), minutes * 60 * 1000)
  2. cambie la llamada interna setTimeout de la misma manera para pasar el parámetro minutes , porque ahora solo pasa undefined . Eso significa immediately para setTimeout .
over 4 years ago · Santiago Trujillo Denunciar

0

ticker espera minutes como argumento, por lo que debe pasar los minutos cuando lo llame dentro de setTimeout . Además de eso, setTimeout espera una función en el primer argumento, por lo que sugiero simplemente pasar una función de flecha que llame a su función ticker . Por favor, compruebe el siguiente código:

 ;(async function ticker (minutes) { try { const res = await coingecko.global() const { market_cap_percentage } = res.data.data dominance = { btc: market_cap_percentage.btc, eth: market_cap_percentage.eth } console.log({ dominance }) } catch (ex) { console.log(ex.message) } finally { setTimeout(() => ticker(minutes), minutes * 60 * 1000) } })(1)
over 4 years ago · Santiago Trujillo Denunciar

0

Creo que la respuesta de jfriend00 ya resolvió el problema. En aras de la legibilidad, le aconsejo un enfoque menos funcional:

 ;(async function ticker (minutes) { while(true) { await new Promise(res => setTimeout(res, minutes * 60 * 1000)); try { const res = await coingecko.global() const { market_cap_percentage } = res.data.data dominance = { btc: market_cap_percentage.btc, eth: market_cap_percentage.eth } console.log({ dominance }) } catch (ex) { console.log(ex.message) } } })(1)
over 4 years ago · Santiago Trujillo Denunciar

0

Aquí hay una solución demasiado complicada y probablemente no adecuada, setInterval . Solo quería mostrar cómo podemos usar setInterval para lograr el mismo comportamiento.

 const fetch = require('isomorphic-fetch') const url = 'https://jsonplaceholder.typicode.com/posts'; const closeThis = () => { let ids = []; async function executeThisShiz(minutes) { ids.forEach((id) => { clearInterval(id); }) try { let res = await fetch(url); res = await res.json(); console.log('yay') return res; } catch(e) { // maybe abort the timer idk? console.log('error', e); } finally { id = setInterval(() => { executeThisShiz(minutes); }, minutes*60*1000); ids.push(id); } } return { ids, executeThisShiz } } const {executeThisShiz} = closeThis(); executeThisShiz(0.1);
over 4 years ago · Santiago Trujillo Denunciar

0

Ya hay algunas buenas explicaciones aquí, pero voy a refactorizar un poco el código para aprovechar async/await sin necesidad de una biblioteca externa.

Primero, hagamos que setTimeout sea una función asíncrona:

 async function sleep(ms) { return new Promise(res => setTimeout(res, ms)); }

A continuación, usemos eso en lugar de setTimeout :

 (async function ticker (minutes) { do { await sleep(minutes * 60 * 1000); await loadData(); } while (true); async function loadData() { try { const res = await coingecko.global() const { market_cap_percentage } = res.data.data dominance = { btc: market_cap_percentage.btc, eth: market_cap_percentage.eth } } catch (err) { console.error(ex.message); } } })(1)

Esto funciona más o menos igual excepto

  1. Espera un minuto una vez que se inicia el servidor.
  2. Siempre esperará un minuto entre solicitudes.

También es mucho más fácil de entender y leer, y dado que usa async/await, se adhiere a un solo paradigma (en lugar de usar async/await y devoluciones de llamada para setTimeout ).

over 4 years ago · Santiago Trujillo 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