0

I would this function to run every 5 seconds and get new data. The getGas() function is an async-await function in and of itself and works fine if I just call let gas = await getGas();. The issue is that I need it to run every 5 seconds and get a new gas price. I'm having trouble understanding how to call this function and have it run every 5 seconds.

async function main() {
  // get the current gwei prices & new price every 5 seconds

  let gas = async () => {
    setTimeout(() => {
      await getGas();
    }, 5000);
  };

  console.log(gas);

  // other code down here
}
itzmurd4
  • 663
  • 10
  • 25
  • Does this answer your question? [Combination of async function + await + setTimeout](https://stackoverflow.com/questions/33289726/combination-of-async-function-await-settimeout) – Naren Oct 08 '21 at 23:04

3 Answers3

1

hmm.. I would just make the setTimeout a Promise in itself and then have gas as an async function to call..

async function main() {
  // get the current gwei prices & new price every 5 seconds

  let gas = async () => {
    return new Promise(r=>{
      setTimeout(async()=>r(await getGas()),5e3);
    })
  }

  console.log(await gas()); //whatever getGas should be

  // other code down here

  //whenever you want gas, you can just "await gas()"
}

However.. if you just didn't word your question correctly and you want the variable gas to be updated every 5 seconds in that block of code within recalling main

an async function to call..

async function main() {
  // get the current gwei prices & new price every 5 seconds

  let gas = null; //starting value
  setInterval(async()=>gas=await getGas(),5e3); //every 5 seconds, gas is updated

  console.log(gas); //null
  setTimeout(()=>console.log(gas),6e3); //whatever getGas should be
  // other code down here

  //whenever you want gas, you can just "gas"
}

EDIT: you told me it doesn't work so I give a live example and am now asking how

async function getGas(){
  return Math.floor(Math.random()*5)
}

async function main1() {
  // get the current gwei prices & new price every 5 seconds

  let gas = async () => {
    return new Promise(r=>{
      setTimeout(async()=>r(await getGas()), 5e3);
    })
  }

  setInterval(async()=>
    console.log(await gas(),"~ main1") //whatever getGas should be
  ,1e3);
  // other code down here

  //whenever you want gas, you can just "await gas()"
}

async function main2() {
  // get the current gwei prices & new price every 5 seconds

  let gas = null; //starting value
  setInterval(async()=>gas=await getGas(),5e3); //every 5 seconds, gas is updated

  console.log(gas); //null
  setInterval(()=>
    console.log(gas,"~ main2") //whatever getGas should be
  ,1e3);
  // other code down here

  //whenever you want gas, you can just "gas"
}
main1(); main2();
The Bomb Squad
  • 4,192
  • 1
  • 9
  • 17
0

If you want to use setTimeout for that then the callback needs to invoke the function that calls setTimeout again, e.g.

(async function main() {
  const gas = await getGas();
  // do stuff with gas

  setTimeout(main, 5000); // call main again after 5 seconds
}());
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 1
    The only problem is that I cannot recall main. The gas variable has needs to update whatever is inside of main and main runs continuously until the user stops. – itzmurd4 Oct 08 '21 at 23:18
  • Why can't you recall `main`? @itzmurd4. – Andy Oct 08 '21 at 23:35
  • because there's another function within main that run continuously sending transactions to the blockchain as each new block is mined. If i run main again, it would send multiple transactions every 5 seconds onto the same block. So its essentially listening for a new block and then sending a new tx. – itzmurd4 Oct 08 '21 at 23:41
  • @itzmurd4: You can put that logic into another function if necessary. You are not providing a lot of information about your problem (e.g. how `gas` is going to be used). Maybe this is an [XY problem](https://xyproblem.info/). Mine is a valid answer to the problem *"I would this function to run every 5 seconds and get new data."* If your problem is more complex, please provide more information. – Felix Kling Oct 09 '21 at 17:36
0

Your setTimeout doesn't need to be wrapped in its own async function. Just call main, log the data, and then call main again.

function mockApi(page) {
  return new Promise((res, rej) => {
    setTimeout(() => res(page), 1000);
  });
}

async function main(page = 1) {
  const data = await mockApi(page);
  console.log(`Data: ${data}`);
  setTimeout(main, 1000, ++page);
}

main();
Andy
  • 61,948
  • 13
  • 68
  • 95