Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive setTimeout with async/await

Tags:

I'm running a setTimeout, recursively, so I only want to call the API one time per minute.

Here is my code:

;(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) 

The problem is:

  • When I start my server, it calls the API immediately
  • It takes one minute to make a second call (expected behaviour)
  • After the second call, it starts calling the API sequentially, without a timeout
like image 733
André Alçada Padez Avatar asked Jan 24 '21 19:01

André Alçada Padez


Video Answer


1 Answers

It calls it immediately because that's what your code does. It executes the ticker(1) function call immediately.

When you call ticker from the setTimeout(ticker, ...), you aren't passing the minutes parameter to that function - that's why the setTimeout() doesn't delay properly.

If you don't want it executed immediately, then get rid of the IIFE and just start it with a setTimeout(). And, then when you call ticker() from the setTimeout() callback, be sure to pass the minutes arguments to it, either by passing the third argument to setTimeout() or by making a little callback function for it.

Here's one implementation:

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); 
like image 109
jfriend00 Avatar answered Sep 21 '22 20:09

jfriend00